C# Linq到SQL转换失败以及本地计算失败
好的,我有以下linq到sql查询:C# Linq到SQL转换失败以及本地计算失败,c#,sql,linq,.net-core,linq-to-sql,C#,Sql,Linq,.net Core,Linq To Sql,好的,我有以下linq到sql查询: var baseQuery = _context.AuditTransaction .Include(at => at.AuditEntityEntries) .ThenInclude(aee => aee.AuditPropertyEntries) .Where(at => auditTransactionFilter.Id == 0 || at.Id == auditTransactionFilter.Id)
var baseQuery = _context.AuditTransaction
.Include(at => at.AuditEntityEntries)
.ThenInclude(aee => aee.AuditPropertyEntries)
.Where(at => auditTransactionFilter.Id == 0 || at.Id == auditTransactionFilter.Id)
.Where(at =>
string.IsNullOrWhiteSpace(auditTransactionFilter.UserName) ||
at.UserName == auditTransactionFilter.UserName);
return baseQuery
.Where(at => at.AuditEntityEntries.Any() || at.AuditEntityEntries
.Any(ataee => auditTransactionFilter.AuditEntityEntries
.Any(atfaee =>
(atfaee.Id == 0 || ataee.Id == atfaee.Id) &&
(string.IsNullOrWhiteSpace(atfaee.TableName) ||
ataee.TableName.ToLower().Contains(atfaee.TableName.ToLower()))
&&
(string.IsNullOrWhiteSpace(atfaee.KeyValues) ||
ataee.KeyValues.ToLower().Contains(atfaee.KeyValues.ToLower()))
&& (atfaee.AuditPropertyEntries.Any() || ataee.AuditPropertyEntries
.Any(atape => atfaee.AuditPropertyEntries
.Any(atfape =>
(atfape.Id == 0 || atape.Id == atfape.Id) &&
(string.IsNullOrWhiteSpace(atfape.PropertyName) ||
atape.PropertyName == atfape.PropertyName)
&&
(string.IsNullOrWhiteSpace(atfape.AuditType.ToString()) ||
atape.AuditType == atfape.AuditType)
&&
(atfape.PropertyValues == null ||
atape.PropertyValues.Contains(atfape.PropertyValues))
))
)
)
));
无论出于何种原因,当它运行时,我收到数百条警告,其中的各个部分无法翻译,将在本地进行评估。但是,查询运行时并没有正确过滤掉不匹配项:返回数据库中的所有记录
但是,当我返回baseQuery.ToList()时,其中(…)查询运行得非常好
更新:即使是一个简单的查询,如:
return baseQuery
.Where(at => at.AuditEntityEntries.Any(ataee => auditTransactionFilter.AuditEntityEntries.Any(atfaee => atfaee.TableName == ataee.TableName)));
返回如下错误:
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'where ([atfaee].TableName == [ataee].TableName)' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Any()' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'where {from AuditEntityEntry atfaee in __auditTransactionFilter_AuditEntityEntries_0 where ([atfaee].TableName == [ataee].TableName) select [atfaee] => Any()}' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'where ([atfaee].TableName == [ataee].TableName)' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Any()' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'where ?= (Property([at], "Id") == Property([ataee], "AuditTransactionId")) =?' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
我做错了什么
请帮忙。好吧,我已经厌倦了试图找到解决linq to sql嵌套Any()语句的方法,所以,我从LinqKit中引入了一个predicateBuilder库
var baseQuery = _context.AuditTransaction
.Include(at => at.AuditEntityEntries)
.ThenInclude(aee => aee.AuditPropertyEntries)
.Where(at => auditTransactionFilter.Id == 0 || at.Id == auditTransactionFilter.Id)
.Where(at => string.IsNullOrWhiteSpace(auditTransactionFilter.UserName) || at.UserName == auditTransactionFilter.UserName);
var queryPredicateBuilder = PredicateBuilder.New<AuditTransaction>();
foreach (var entityFilter in auditTransactionFilter.AuditEntityEntries)
{
if(entityFilter.AuditPropertyEntries?.Count == 0)
{
queryPredicateBuilder
.Or(at => at.AuditEntityEntries
.Any(ataee => ataee.TableName.Contains(entityFilter.TableName)
&& (ataee.KeyValues == entityFilter.KeyValues || string.IsNullOrWhiteSpace(entityFilter.KeyValues))));
}
}
foreach (var propertyFilter in auditTransactionFilter.AuditEntityEntries.SelectMany(atfaee => atfaee.AuditPropertyEntries))
{
queryPredicateBuilder
.Or(at => at.AuditEntityEntries
.Any(ataee => ataee.TableName.Contains(propertyFilter.AuditEntityEntry.TableName)
&& (ataee.KeyValues == propertyFilter.AuditEntityEntry.KeyValues || string.IsNullOrWhiteSpace(propertyFilter.AuditEntityEntry.KeyValues))
&& ataee.AuditPropertyEntries
.Any(atape => atape.PropertyName == propertyFilter.PropertyName && atape.PropertyValues.Contains(propertyFilter.PropertyValues))
));
}
return baseQuery.AsExpandable().Where(queryPredicateBuilder);
var baseQuery=\u context.AuditTransaction
.Include(at=>at.AuditEntityEntries)
。然后包括(aee=>aee.AuditPropertyEntries)
.Where(at=>auditTransactionFilter.Id==0 | | at.Id==auditTransactionFilter.Id)
.Where(at=>string.IsNullOrWhiteSpace(auditTransactionFilter.UserName)| | at.UserName==auditTransactionFilter.UserName);
var queryPredicateBuilder=PredicateBuilder.New();
foreach(auditTransactionFilter.AuditEntityEntries中的变量entityFilter)
{
if(entityFilter.AuditPropertyEntries?.Count==0)
{
查询预测生成器
.或(at=>at.AuditEntityEntries
.Any(ataee=>ataee.TableName.Contains(entityFilter.TableName)
&&(ataee.KeyValues==entityFilter.KeyValues | | string.IsNullOrWhiteSpace(entityFilter.KeyValues));
}
}
foreach(auditTransactionFilter.AuditEntityEntries.SelectMany中的var propertyFilter(atfaee=>atfaee.AuditPropertyEntries))
{
查询预测生成器
.或(at=>at.AuditEntityEntries
.Any(ataee=>ataee.TableName.Contains(propertyFilter.AuditEntityEntry.TableName)
&&(ataee.KeyValues==propertyFilter.AuditEntityEntry.KeyValues | | string.IsNullOrWhiteSpace(propertyFilter.AuditEntityEntry.KeyValues))
&&ataee.AuditPropertyEntries
.Any(atape=>atape.PropertyName==propertyFilter.PropertyName&&atape.PropertyValues.Contains(propertyFilter.PropertyValues))
));
}
返回baseQuery.AsExpandable().Where(queryPredicateBuilder);
这完全成功了!
我不喜欢它,但它可以工作,我不知道如何生成一个动态linq-to-sql语句,该语句将正确地进行转换,并根据外部非原语列表嵌套这么多级别的任何检查
我仍在寻找更好的答案。“当它运行时,我会收到数百条警告”您在运行时收到警告?此外,您的
return
语句中的Where
子句可以简化为第一个条件,因为的第二部分是第一个条件的过滤版本(如果第一个是true
,那么第二个总是true
)。您可以将其简化为返回baseQuery.Where(at=>at.AuditEntityEntries.Any()
@Rufus,当查询执行时,运行时会出现警告。谢谢,我已经将所有冗余的空安全检查修改为just.Any()。我仍然收到警告。此外,我添加了一个嵌套迭代的简单尝试,但失败了。我更新了问题以反映。