Fork me on GitHub

EntityFramework 7 smallint short 奇怪问题(已解决)

在使用 EF7 进行条件查询的时候,遇到一个很奇怪的问题,不知道 EF 其他版本有没有这种情况,怎么说呢?一句话描述不清楚,具体请看下面内容。

问题场景

BloggingContext 配置代码:

using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata;
using System.Collections.Generic;

namespace EF7
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        protected override void OnConfiguring(DbContextOptions builder)
        {
            builder.UseSqlServer(@"Server=.;Database=Blogging;Trusted_Connection=True;");
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Blog>()
                .OneToMany(b => b.Posts, p => p.Blog)
                .ForeignKey(p => p.BlogId);
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public short BlogCateId { get; set; }//注意这里

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

注意 Blog 实体中 BlogCateId 的属性类型为 short,使用 EF7 进行映射的时候,会映射对应字段类型为 smallint,Blog 生成表结构:

然后进行 BlogId 和 BlogCateId 的条件查询,示例代码:

[Fact]
public void ContextLoad_Test()
{
    using (var context = new BloggingContext())
    {
        var count = context.Blogs.Where(b => b.BlogId == 1 && b.BlogCateId == 1).Count();
    }
}

SQL Profiler 抓取生成的 SQL 代码:

奇怪的问题来了,上面测试代码条件,我明明写的是b.BlogId == 1 && b.BlogCateId == 1,但是生成出来的 SQL 代码,却只有 BlogId 查询条件,BlogCateId 条件跑哪去了???另外,注意我使用 Linq 查询的是 Count,也就是说生成的 SQL 代码应该为SELECT COUNT(*)...,但上面生成的 SQL 代码却并不是这样。很奇怪的问题,难道说 EF7 不支持 smallint 或 short 类型?如果按照 SQL Profiler 生成的 SQL,也就是说,我们使用 EF7 要避免这种问题,因为 short 类型的字段并没有被查询,但后来我自己又做了一个测试,Blog 表数据:

测试代码及结果:

SQL Profiler 抓取生成的 SQL 代码:

查询的条件只有 BlogCateId,根据 Blog 表中的数据,可以得到查询结果没有什么问题,但是生成的 SQL 代码却完全不一样,不知道是什么原因?如果看着生成的 SQL 代码“不舒服”,可以把 BlogCateId 的 short 类型改为 int,对应字段类型也改为 int,用第一次的测试代码生成的 SQL 代码:

这才是我们想要的效果,关于这个问题,还请园友们指教。


感谢园友 JeffreyWu 的指正,下面写法是正确的:

[Fact]
public void ContextLoad_Test()
{
    using (var context = new BloggingContext())
    {
        var count = context.Blogs.Where(b => b.BlogId == 1 && b.BlogCateId.Equals(1)).Count();//==更改为Equals
    }
}
posted @ 2014-12-01 18:47  田园里的蟋蟀  阅读(2278)  评论(20编辑  收藏  举报