C# 如何将LINQ中的Contains用于具有任意属性选择的实体,而不计算IQueryable?
我试图为具有明确的子-父关系的实体创建一个通用存储库。F.e.带有审核日志的审核日志条目C# 如何将LINQ中的Contains用于具有任意属性选择的实体,而不计算IQueryable?,c#,entity-framework,linq,expression,iqueryable,C#,Entity Framework,Linq,Expression,Iqueryable,我试图为具有明确的子-父关系的实体创建一个通用存储库。F.e.带有审核日志的审核日志条目 公共类BaseWithParentRepository:BaseRepository,IRepositoryWithParentWhere tenty:class,IDbEntityWithKey,new() { public Func ParentKeySelector{get;set;} public BaseWithParentRepository(IDbContext上下文,Func parentK
公共类BaseWithParentRepository:BaseRepository,IRepositoryWithParentWhere tenty:class,IDbEntityWithKey,new()
{
public Func ParentKeySelector{get;set;}
public BaseWithParentRepository(IDbContext上下文,Func parentKeySelector):base(context)
{
ParentKeySelector=ParentKeySelector;
}
公共IQueryable QueryParentKey(TParentKey parentKey)
{
IEnumerable parentId=新的TParentKey[]{parentKey};
返回Query.Where(e=>parentId.Contains(ParentKeySelector(e));
}
}
AuditLogDetail类是:
public类AuditLogDetail:BaseDbEntity
{
公共Guid AuditLogId{get;set;}
公共虚拟审核日志审核日志{get;set;}
公共字符串字段{get;set;}
公共字符串OldValue{get;set;}
公共字符串NewValue{get;set;}
}
AuditLogDetails存储库将是:
公共类AuditLogDetailRepository:BaseWithParentRepository,IAAuditLogDetailRepository
{
公共AuditLogDetailRepository(IDbContext上下文):基本(上下文,ald=>ald.AuditLogId)
{
}
}
如您所见,BaseWithParentRepository
的构造函数的第二个参数是属性选择器,方法queryParentKey
尝试获取父实体(AuditLog)的所有AuditLogDetails
但是,调用queryparentkey
方法时,会引发以下异常:
Error: System.NotSupportedException: The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.NotSupportedTranslator.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.TranslateContains(ExpressionConverter parent, Expression sourceExpression, Expression valueExpression)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass41_0.<GetResults>b__1()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass41_0.<GetResults>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__31_0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Manu.Data.BaseWithParentRepository`3.GetAllByParentKey(TParentKey parentKey)
错误:System.NotSupportedException:LINQ to实体中不支持LINQ表达式节点类型“Invoke”。
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.NotSupportedTranslator.Translate(ExpressionConverter父级,Expression linq)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.TranslateExpression(表达式linq)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.ContainesTranslator.TranslateContains(ExpressionConverter父级、Expression sourceExpression、Expression valueExpression)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.ContainesTranslator.Translate(ExpressionConverter父级,MethodCallExpression调用)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter父级,MethodCallExpression调用,SequenceMethod SequenceMethod)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter父级,MethodCallExpression linq)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter父级,Expression linq)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.TranslateExpression(表达式linq)
位于System.Data.Entity.Core.Objects.eliq.ExpressionConverter.TranslateLambda(LambdaExpression lambda,DbExpression input)
位于System.Data.Entity.Core.Objects.eliq.ExpressionConverter.TranslateLambda(LambdaExpression lambda、DbExpression input、DbExpressionBinding&binding)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter父级、MethodCallExpression调用、DbExpression和source、DbExpressionBinding和sourceBinding、DbExpression和lambda)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter父级,MethodCallExpression调用)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter父级,MethodCallExpression调用,SequenceMethod SequenceMethod)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter父级,MethodCallExpression linq)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter父级,Expression linq)
位于System.Data.Entity.Core.Objects.Elink.ExpressionConverter.TranslateExpression(表达式linq)
位于System.Data.Entity.Core.Objects.elink.ExpressionConverter.Convert()处
位于System.Data.Entity.Core.Objects.elink.elinkQueryState.GetExecutionPlan(可为null的`1 forMergeOption)
在System.Data.Entity.Core.Objects.ObjectQuery`1.c_uu DisplayClass41_0.b_u 1()
在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 Func,IDBEcutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)
在System.Data.Entity.Core.Objects.ObjectQuery`1.c_uuuuDisplayClass41_0.b_uuu0()
在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1操作)中
位于System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(可为null`1 forMergeOption)
位于System.Data.Entity.Core.Objects.ObjectQuery`1.b_uuu31_u0()
位于System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
位于System.Collections.Generic.List`1..ctor(IEnumerable`1集合)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
位于Manu.Data.BaseWithParentRepository`3.GetAllByParentKey(TParentKey parentKey)
我知道在
包含中调用ParentKeySelector
不能转换为SQL。所以我似乎应该用Expression
而不是Func
来做我想做的事情,但我不知道如何实现我的目标。请更熟悉表达式的人帮帮我好吗?您是正确的,ParentKeySelector无法转换为SQL是问题的原因。由于无法将其转换为SQL,因此不可能将linq转换为SQL以供DB服务器(而不是m)执行