我正在尝试编写一个将IQueryable<T>
转换为IQueryable<CustomType<T, K>>
的函数,然后可以在以后根据需要将其转换为IEnumerable<CustomType<T, K>>
。
给出:
public struct CustomType<TModel, TKey>
{
public TKey Key { get; set; }
public TModel Value { get; set; }
}
如果我写:
var list = await query
.Select(selectExpression) // Selects into `CustomType<T, K>`
.Where(whereExpression)
.OrderBy(orderByExpression)
.Select(x => new { Value = x.Value })
.ToListAsync();
其中selectExpression
是运行时构建的表达式,等效于:
x => new CustomType<T, K> { Key = ..., Value = ... }
然后一切都按预期工作,并将在运行时构建的selectExpression
转换为单个SQL表达式。
但是,如果我在任何时候返回CustomType<T, K>
,例如:
var list = await query
.Select(selectExpression) // Selects into `CustomType<T, K>`
.ToListAsync();
然后EF Core抱怨在某些实体跟踪功能CustomType<T, K>
中违反了一些约束TIn
(为什么要尝试跟踪自定义类型?)
特定的错误代码是此代码(对于CustomType<OtherType, int>
):
GraphQL.ExecutionError: GenericArguments[1], 'CustomType`2[OtherType,System.Int32]', on 'System.Collections.Generic.IAsyncEnumerable`1[TOut] _TrackEntities[TOut,TIn](System.Collections.Generic.IAsyncEnumerable`1[TOut], Microsoft.EntityFrameworkCore.Query.QueryContext, System.Collections.Generic.IList`1[Microsoft.EntityFrameworkCore.Query.Internal.EntityTrackingInfo], System.Collections.Generic.IList`1[System.Func`2[TIn,System.Object]])' violates the constraint of type 'TIn'. ---> GraphQL.Conventions.Execution.FieldResolutionException: GenericArguments[1], 'CustomType`2[OtherType,System.Int32]', on 'System.Collections.Generic.IAsyncEnumerable`1[TOut] _TrackEntities[TOut,TIn](System.Collections.Generic.IAsyncEnumerable`1[TOut], Microsoft.EntityFrameworkCore.Query.QueryContext, System.Collections.Generic.IList`1[Microsoft.EntityFrameworkCore.Query.Internal.EntityTrackingInfo], System.Collections.Generic.IList`1[System.Func`2[TIn,System.Object]])' violates the constraint of type 'TIn'. ---> System.ArgumentException: GenericArguments[1], 'Persistence.IQueryableExtensions+OrderedGroupItem`2[OtherType,System.Int32]', on 'System.Collections.Generic.IAsyncEnumerable`1[TOut] _TrackEntities[TOut,TIn](System.Collections.Generic.IAsyncEnumerable`1[TOut], Microsoft.EntityFrameworkCore.Query.QueryContext, System.Collections.Generic.IList`1[Microsoft.EntityFrameworkCore.Query.Internal.EntityTrackingInfo], System.Collections.Generic.IList`1[System.Func`2[TIn,System.Object]])' violates the constraint of type 'TIn'. ---> System.Security.VerificationException: Method Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider._TrackEntities: type argument 'Persistence.IQueryableExtensions+OrderedGroupItem`2[OtherType,System.Int32]' violates the constraint of type parameter 'TIn'.
at System.RuntimeMethodHandle.GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation)
at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
--- End of inner exception stack trace ---
at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.TrackEntitiesInResults[TResult](QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator()
at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable`1 source, TAccumulate seed, Func`3 accumulator, Func`2 resultSelector, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 118
如何使它工作,以便ToListAsync
在使LINQ to SQL工作(意味着构建一个SQL表达式)的同时返回CustomType<T, K>
?
我尝试将CustomType
设为class
,但是由于某种原因,由于自定义,LINQ to SQL无法为selectExpression
生成单个SQL表达式类型为class
。