文章出處

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

文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()