ToLower in Array.Contains in Entity Framework Core

时间:2017-07-24 14:11:47

标签: postgresql entity-framework entity-framework-core

似乎在EF Core的查询中,如#include<bits/stdc++.h> using namespace std; int expmod(int n, int p, int m) { if (p == 0) return 1; int nm = n % m; long long r = expmod(nm, p / 2, m); r = (r * r) % m; if (p % 2 == 0) return r; return (r * nm) % m; } int main(){ long long n,m; cin>>n>>m; long long r = 0; for (int i = 1; i <= n; ++i) r = (r + expmod(i, i, m)) % m; cout<<r+1<<endl; } 过滤部分未在sql server上执行,因此没有构建'where'关闭。我正在使用postgresql和npgsql驱动程序,但我已经检查过ms sql server的相同行为。 所以,你知道是否有可能构建查询,这将生成像这样的子句(对于postgresql): myContext.Books.Where(b => new [] { "harry potter", "the lord of the rings" }.Contains(b.Title.ToLower()))

2 个答案:

答案 0 :(得分:1)

你的linq语句对于松散匹配来说似乎有些偏差。

class Program
  {
    static void Main(string[] args)
    {
      var contextMock = new List<Book>
      {
        new Book(1, "Harry Potter and The Sorcerer's Stone", "Fiction"),
        new Book(2, "Harry Potter and The Secret Chamber", "Fiction"),
        new Book(3, "Dune", "Fiction"),
        new Book(4, "The Lord of The Rings The Fellowship of the Ring", "Fiction"),
        new Book(5, "The Lord of The Rings Return of the King", "Fiction"),
        new Book(6, "A Brief History of Time", "NonFiction")
      };


      var wrong = contextMock.Where(x => (new[]{ "harry potter", "the lord of the rings" }).Contains(x.Title.ToLower())).ToList();
      var right = contextMock.Where(x => (new List<string> { "harry potter", "the lord of the rings" }).Any(y => x.Title.ToLower().Contains(y.ToLower()))).ToList();

      Console.ReadLine();
    }
  }

答案 1 :(得分:1)

您正在进行限制EF Core SQL翻译。最高版本1.1.2 EF核心假设在Array.Contains(item)中,item将是成员表达式或EF.Property方法调用,指示属性访问。但在您的情况下,您有一个不同的方法调用,因为您正在调用ToLower()因此EF Core无法识别该模式并且不会将Contains转换为服务器。

同时,在修复不同的issue时删除了此限制。 如果可能,现在EF Core翻译item。由于可以翻译ToLower(),因此它可以正常工作并生成IN语句。该问题已在2.0.0-preview1中修复。所以它应该在2.0版本的EF Core中提供。

我用每晚2.0.0的EF Core测试了这个查询。以下是生成的SQL。

SELECT [x].[Id], [x].[Title]
FROM [Blogs] AS [x]
WHERE LOWER([x].[Title]) IN (N'harry potter', N'the lord of the rings')