C# 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)

好的,我有以下linq到sql查询:

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()。我仍然收到警告。此外,我添加了一个嵌套迭代的简单尝试,但失败了。我更新了问题以反映。