2017-07-24 88 views
1

似乎在EF Core的查询如myContext.Books.Where(b => new [] { "harry potter", "the lord of the rings" }.Contains(b.Title.ToLower()))中,过滤部分不在sql server上执行,没有'where'关闭构建。我正在使用postgresql和npgsql驱动程序,但我已经检查过相同的行为是为MS SQL服务器。 所以,你知道是否有可能建立查询系统将生成SQL WHERE这样的条款(PostgreSQL的): where lower(title) in ('harry potter', 'the lord of the rings')ToLower in Array.Contains in Entity Framework核心

回答

1

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

同时在修复不同的issue时删除了此限制。 如果可能,现在EF Core会翻译item。由于ToLower()是可以被翻译的,所以它可以正常工作并生成IN声明。该问题已在2.0.0-preview1中解决。所以它应该可以在EF Core的2.0版本中使用。

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

SELECT [x].[Id], [x].[Title] 
FROM [Blogs] AS [x] 
WHERE LOWER([x].[Title]) IN (N'harry potter', N'the lord of the rings') 
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(); 
    } 
    } 
+0

它没有帮助。正如我写的,我希望EF用'where'('harry potter','the rings of the Lord's')中的lower(title)'生成sql,但现在它只生成'select ... from ...'获取整个表格,然后在内存中进行过滤。 – hmisko

+0

???除非您重写T4模板,否则EF不会生成查询。 Postgresql只是数据库的一种风格。除非你有其他的npgsql只是一个驱动程序。因此,如果没有更多的数据,你只是提出一个谓词,在哪里,你是否把你失去匹配的意图是错误的。如果它生成的地方你没有提供这个细节。我刚刚看到了linq',(b => ...)',并且看到它的意图是错误的。 – djangojazz