在使用 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
}
}