最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Entity?Framework?Core實現(xiàn)Like查詢詳解

 更新時間:2022年02月22日 10:49:23   作者:Sweet-Tang  
本文詳細講解了Entity?Framework?Core實現(xiàn)Like查詢的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

在Entity Framework Core 2.0中增加一個很酷的功能:EF.Functions.Like(),最終解析為SQL中的Like語句,以便于在 LINQ 查詢中直接調(diào)用。

不過Entity Framework 中默認提供了StartsWith、ContainsEndsWith方法用于解決模糊查詢,那么為什么還要提供EF.Functions.Like,今天我們來重點說說它們之間的區(qū)別。

表結(jié)構(gòu)定義

在具體內(nèi)容開始之前,我們先簡單說明一下要使用的表結(jié)構(gòu)。

    public class Category
    {
        public int CategoryID { get; set; }
        public string CategoryName { get; set; }
        
        public override string ToString()
        {
            return $"{nameof(CategoryID)}: {CategoryID}, {nameof(CategoryName)}: {CategoryName}";
        }
    }

在 Category 類型定義了兩個字段:CategoryID、CategoryName。

    public class SampleDbContext : DbContext
    {
        public virtual DbSet<Category> Categories { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("數(shù)據(jù)庫連接字符串");
            base.OnConfiguring(optionsBuilder);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            EntityTypeBuilder<Category> entityTypeBuilder = modelBuilder.Entity<Category>();
            entityTypeBuilder.ToTable("Category");
            entityTypeBuilder.HasKey(e => e.CategoryID);
            entityTypeBuilder.Property(e => e.CategoryID).UseSqlServerIdentityColumn();
        }
    }

我們使用 SampleDbContext 來訪問數(shù)據(jù)庫。

CategoryIDCategoryName
1Clothing
2Footwear
3Accessories

在數(shù)據(jù)庫的 Category 表中插入上面三行記錄。

EF.Functions.Like 使用示例

我們來看一個EF.Functions.Like()查詢示例,查詢 CategoryName 字段中包括字符串 “t” 的數(shù)據(jù),傳遞的參數(shù)是 “%t%”:

        [Fact]
        public void Like()
        {
            using (var dataContext = new SampleDbContext()) {

               var result= dataContext.Categories.Where(item => EF.Functions.Like(item.CategoryName, "%t%")).ToList();
           
                foreach (var item in result) {
                    _testOutputHelper.WriteLine(item.CategoryName);
                }
            }
        }

提示:在做一些示例演示時,個人喜歡會用 Xunit + Resharper,這樣可以直接運行對應的示例,并且也可以直接輸出對應的結(jié)果。

我們來看一下運行的結(jié)果:

查詢的結(jié)果包含兩條數(shù)據(jù),這與我們預期結(jié)果一致。

字符串匹配模式

在這里,我暫且將StartsWith、ContainsEndsWith方法稱之為字符串匹配模式

您肯定在Entity Framework中使用過這些方式,我們還是簡單說明一下這三個方法的作用:

  • StartsWith:表示字符串的開頭是否與指定的字符串匹配;
  • Contains:表示指定的子串是否出現(xiàn)在此字符串中;
  • EndsWith:表示字符串的結(jié)尾是否與指定的字符串匹配;

我們可以通過Contains方法實現(xiàn)與前一個示例一致的功能:

        [Fact]
        public void Contains()
        {
            using (var dataContext = new SampleDbContext())
            {
                var result = dataContext.Categories.Where(item => item.CategoryName.Contains("t")).ToList();

                foreach (var item in result)
                {
                    _testOutputHelper.WriteLine(item.CategoryName);
                }

            }
        }

我們在Contains方法轉(zhuǎn)入?yún)?shù)“t” ,運行的結(jié)果如下:

運行結(jié)果與 Like 函數(shù)示例的結(jié)果是一致的。

在這里我只列舉了Contains的示例,StartsWithEndsWith的功能非常相似,我就不重復列舉了。

這兩個示例的運行結(jié)果是一致的,那么微軟為什么要提供EF.Functions.Like()方法呢?

通配符模糊查詢

我們知道在 T-SQL 語句中 Like 關(guān)鍵字支持 通配符 ,下面簡單介紹支持的通配符:

通配符說明示例
%包含零個或多個字符的任意字符串。WHERE title LIKE '%computer%' 將查找在書名中任意位置包含單詞 "computer" 的所有書名。
_(下劃線)任何單個字符。WHERE au_fname LIKE '_ean' 將查找以 ean 結(jié)尾的所有 4 個字母的名字(Dean、Sean 等)。
[ ]指定范圍 ([a-f]) 或集合 ([abcdef]) 中的任何單個字符。WHERE au_lname LIKE '[C-P]arsen' 將查找以 arsen 結(jié)尾并且以介于 C 與 P 之間的任何單個字符開始的作者姓氏,
例如 Carsen、Larsen、Karsen 等。
[^]不屬于指定范圍 ([a-f]) 或集合 ([abcdef]) 的任何單個字符。WHERE au_lname LIKE 'de[^l]%' 將查找以 de 開始并且其后的字母不為 l 的所有作者的姓氏。

關(guān)于 Like 和通配符更多的知識請直接到MSDN中了解,鏈接地址:https://msdn.microsoft.com/zh-cn/library/ms179859(v=sql.110).aspx。

我們的將查詢關(guān)鍵字由 “t” 改為 “[a-c]”,再來看上面兩個示例分別運行的結(jié)果:

EF.Functions.Like 查詢示例:

Contains 查詢示例:

上面運行的結(jié)果,Like 查詢的結(jié)果返回三條記錄,而 Contains 查詢的結(jié)果無任何數(shù)據(jù)返回。

我們借助 SQL Server Profiler 分別捕獲這兩個示例實際生成的SQL查詢。

EF.Functions.Like 查詢生成的SQL語句:

    SELECT [item].[CategoryID], [item].[CategoryName]
    FROM [Category] AS [item]
    WHERE [item].[CategoryName] LIKE N'%[a-c]%'

Contains 查詢生成的SQL語句:

    SELECT [item].[CategoryID], [item].[CategoryName]
    FROM [Category] AS [item]
    WHERE CHARINDEX(N'[a-c]', [item].[CategoryName]) > 0

通過上面示例以及捕獲的SQL,我們可以得知,EF.Functions.Like() 查詢會被解釋成為 Like,實際上是查詢字符串中包括 “a”、“b”、“c” 這三個字符中任何一個字符的數(shù)據(jù),而使用 Contains 查詢會被解析成為 CharIndex 函數(shù),實際是指查詢字符串中包括 “[a-c]” 的字符串。

提示: StartsWithEndsWith分別會被解析成為LeftRight函數(shù),測試結(jié)果在這里不再做重復演示。

結(jié)論: 在EF Core中提供EF.Functions.Like()方法的根本原因是在 TSQL 語句中 Like 關(guān)鍵字支持通配符,而在.Net中StartsWith、ContainsEndsWith方法是不支持通配符的;
在EF Core中StartsWith、ContainsEndsWith模糊查詢實際分別被解析成為Left、CharIndexRight,而不是Like。

其它要點

通過上面的示例我們已經(jīng)說清楚了EF.Functions.Like()方法和StartsWithContainsEndsWith方法之間的區(qū)別,但是還有以下兩點需要說明。

EF Core StartsWith 優(yōu)化

如果使用StartWith方法來實現(xiàn)模糊查詢,解析后的SQL語句會包括一個Like查詢,您可能要說,剛才不是已經(jīng)講過嗎,StartsWith、ContainsEndsWith方法解析后的SQL不是通過 Like 來查詢!先不要著急,我下面來說清楚這個問題。

StartsWith 查詢示例:

        [Fact]
        public void StartsWith()
        {
            using (var dataContext = new SampleDbContext())
            {
                var result = dataContext.Categories.Where(item => item.CategoryName.StartsWith("Clo")).ToList();

                foreach (var item in result)
                {
                    _testOutputHelper.WriteLine(item.CategoryName);
                }
            }
        }

借助 SQL Server Profiler 捕獲實際生成的SQL查詢:

    SELECT [item].[CategoryID], [item].[CategoryName]
    FROM [Category] AS [item]
    WHERE [item].[CategoryName] LIKE N'Clo' + N'%' AND (LEFT([item].[CategoryName], LEN(N'Clo')) = N'Clo')

在SQL語句中,即用到了Like,也用到Left函數(shù),這是為什么呢?

您可能知道在數(shù)據(jù)庫查詢時,如果在某一個字段上使用函數(shù)是無法利用到索引的;在使用Left,CharIndexRight時是無法利用到索引的;而Like查詢在百分號后置的情況下會利用到索引。關(guān)于數(shù)據(jù)庫的這些知識,在博客園上有很多文章,我就不重復說明了。

結(jié)論: StartsWith模糊查詢解析后的SQL用到Like,這是因為Like在百分號后置的是情況下會利用到索引,這樣查詢速度會更快。ContainsEndsWith模糊查詢解析后的SQL不包括Like查詢,因為在分百號前置的情況無法引用到索引。

關(guān)于ContainsEndsWith模糊查詢的測試,在這里不再重復,您可以自己測試。

EF 6

在EF 6中,模糊查詢解析后的SQL語句與EF Core中略有不同,但是執(zhí)行的結(jié)果沒有區(qū)別。

我們在EF 6中分別捕獲StartsWithContainsEndsWith解析后的SQL語句,不過我們搜索的關(guān)鍵字是:“[a-c]”,包含通配符。

StartsWith 查詢生成的SQL語句:

SELECT 
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[CategoryName] AS [CategoryName]
    FROM [dbo].[Category] AS [Extent1]
    WHERE [Extent1].[CategoryName] LIKE N'~[a-c]%' ESCAPE N'~'

Contains 查詢生成的SQL語句:

SELECT 
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[CategoryName] AS [CategoryName]
    FROM [dbo].[Category] AS [Extent1]
    WHERE [Extent1].[CategoryName] LIKE N'%~[a-c]%' ESCAPE N'~'

EndsWith 查詢生成的SQL語句:

SELECT 
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[CategoryName] AS [CategoryName]
    FROM [dbo].[Category] AS [Extent1]
    WHERE [Extent1].[CategoryName] LIKE N'%~[a-c]' ESCAPE N'~'

StartsWith、ContainsEndsWith方法均會被解析為Like查詢,但是是傳遞的參數(shù)由:“[a-c]”變?yōu)榱?ldquo;[a-b]”**,前面多了一個特殊符號**“”,并且查詢子句的后面還多了一部分 ESCAPE N'~'。

在MSDN上面有關(guān)ESCAPE關(guān)鍵字的解釋,我們摘取其中一部分來說明:

使用 ESCAPE 子句的模式匹配搜索包含一個或多個特殊通配符的字符串。 例如,customers 數(shù)據(jù)庫中的 discounts 表可能存儲含百分號 (%) 的折扣值。 若要搜索作為字符而不是通配符的百分號,必須提供 ESCAPE 關(guān)鍵字和轉(zhuǎn)義符。 例如,一個樣本數(shù)據(jù)庫包含名為 comment 的列,該列含文本 30%。 若要搜索在 comment 列中的任何位置包含字符串 30% 的任何行,請指定 WHERE comment LIKE '%30!%%' ESCAPE '!' 之類的 WHERE 子句。 如果未指定 ESCAPE 和轉(zhuǎn)義符,則數(shù)據(jù)庫引擎將返回包含字符串 30 的所有行。

如果您想了解EF 6是如果過濾這些通配符的,可以在Github上面了解,鏈接地址:https://github.com/aspnet/EntityFramework6/blob/6.1.3/src/EntityFramework.SqlServer/SqlProviderManifest.cs#L164-L189

結(jié)論:在EF 6中StartsWith、ContainsEndsWith方法均會被解析為Like查詢,但是如果出現(xiàn)了通配符,框架會結(jié)合ESCAPE以及自身過濾功能將參數(shù)進行轉(zhuǎn)義。

總結(jié)

通過上面的敘述,我們可以得到如下一些結(jié)論:

  • 在EF Core中提供EF.Functions.Like()方法的根本原因是在 TSQL 語句中 Like 關(guān)鍵字支持通配符,而在.Net中StartsWith、ContainsEndsWith方法是不支持通配符的;
  • 在EF Core中StartsWithContainsEndsWith模糊查詢分別被解析成為Left、CharIndexRight,而不是Like。
  • 在EF Core中StartsWith模糊查詢解析后的SQL用到Like,這是因為Like在百分號后置的是情況下會利用到索引,這樣查詢速度會更快;
  • 在EF 6中,StartsWith、ContainsEndsWith方法均會被解析為Like查詢,但是如果出現(xiàn)了通配符,框架會結(jié)合ESCAPE以及自身過濾功能將參數(shù)進行轉(zhuǎn)義;
  • 在EF 6中,模糊查詢不支持通配符,這一點是因為我沒有找到對應的解決方案!

到此這篇關(guān)于Entity Framework Core實現(xiàn)Like查詢的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

安阳县| 洛扎县| 沂南县| 太康县| 三门峡市| 诸城市| 靖宇县| 洪洞县| 宁河县| 晴隆县| 霍山县| 连平县| 堆龙德庆县| 肃北| 阳谷县| 改则县| 辉南县| 胶南市| 湘潭市| 阳山县| 宣威市| 巴里| 塔城市| 三明市| 松滋市| 遂平县| 兖州市| 玉山县| 新乡市| 大田县| 富锦市| 陵川县| 连山| 墨脱县| 墨竹工卡县| 阿鲁科尔沁旗| 县级市| 申扎县| 隆子县| 封开县| 友谊县|