即使在显式包含之后,EF Core“InvalidOperationException:包含已用于非实体可查询”的导航属性也是如此
Posted
技术标签:
【中文标题】即使在显式包含之后,EF Core“InvalidOperationException:包含已用于非实体可查询”的导航属性也是如此【英文标题】:EF Core "InvalidOperationException: Include has been used on non entity queryable" for navigation property even after explicit include 【发布时间】:2020-04-25 07:42:42 【问题描述】:我创建了一个使用以下包的示例项目 -
GraphQL
GraphQL.EntityFramework
System.Linq.Dynamic.Core
这里的想法是翻译在 GraphQL 查询中完成的选择并将其传递给 EntityFramework,以免过度获取查询中未要求的列。为此,我使用System.Linq.Dynamic.Core
以字符串形式传递Select
表达式。我已经看到 EntityFramework github repo 上存在一个问题,用于获取导航属性,其中包含是必须的,正如 here 所讨论的那样。之后,我在制作 Select
之前包含了所需的导航属性,但由于某种原因它抱怨以下错误 -
GraphQL.ExecutionError: Error trying to resolve customers.
---> System.InvalidOperationException: Include has been used on non entity queryable.
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessInclude(NavigationExpansionExpression source, Expression expression, Boolean thenInclude)
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at GraphQL.EntityFramework.EfGraphQLService`1.<>c__DisplayClass26_0`2.<<BuildQueryField>b__0>d.MoveNext() in C:\\projects\\graphql-entityframework\\src\\GraphQL.EntityFramework\\GraphApi\\EfGraphQLService_Queryable.cs:line 130
at GraphQL.Instrumentation.MiddlewareResolver.Resolve(ResolveFieldContext context)
at GraphQL.Execution.ExecutionStrategy.ExecuteNodeAsync(ExecutionContext context, ExecutionNode node)
这是失败的代码
public class QueryTest : QueryGraphType<TestDBContext>
public QueryTest(IEfGraphQLService<TestDBContext> graphQlService) :
base(graphQlService)
Name = "Query";
AddQueryField(
name: "customers",
// the next line is failing
resolve: context => context.DbContext.Customers.Include(x => x.Orders).Select<Customer>(GetSelect(context.SubFields))
);
AddQueryField(
name: "orders",
resolve: context => context.DbContext.Orders.Include(x => x.Customer).Select<Order>(GetSelect(context.SubFields))
);
private string GetSelect(IDictionary<string, Field> subfields) => $"new(string.Join(",", GetSelectedColumns(subfields)))";
private IEnumerable<string> GetSelectedColumns(IDictionary<string, Field> subfields)
foreach (var item in subfields)
if (item.Value.SelectionSet.Children.Count() > 0)
continue;
yield return item.Key;
当我发出以下 GraphQL 查询时
query
customers
customerName
orders
orderID
orderDate
完整的代码示例托管在github 上,而不是在这里粘贴,因为它太长了无法阅读。任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:您是否尝试过这个项目:https://github.com/StefH/GraphQL.EntityFrameworkCore.DynamicLinq?
使用此项目,您可以轻松地将 EF 实体中的所有属性公开为 GraphQL 查询中的可搜索字段。
例如,见https://github.com/StefH/GraphQL.EntityFrameworkCore.DynamicLinq/tree/master/examples/MyHotel
【讨论】:
我今天会尝试一下,让你知道结果如何。 不幸的是,GraphQL.EntityFrameworkCore.DynamicLinq
库并没有完全解决我的问题。我已经打开了一个 Github 问题。以上是关于即使在显式包含之后,EF Core“InvalidOperationException:包含已用于非实体可查询”的导航属性也是如此的主要内容,如果未能解决你的问题,请参考以下文章
.NET Core EF框架使用SQL server 2008数据库分页问题:Incorrect syntax near 'OFFSET'. Invalid usage of the