【问题标题】:EF 7/Core: Getting count of records in child tableEF 7/Core:获取子表中的记录数
【发布时间】:2016-09-17 19:18:06
【问题描述】:

我尝试在 EF Core GitHub 的问题部分提出这个问题/问题,但没有得到任何回应,所以我不得不假设我问错了地方...

我正在使用 EntityFramework.Core 和 EntityFramework.MicrosoftSqlServer 7.0.0-rc1-final 包,我正在尝试通过类似于以下 SQL 的代码来做一些事情:

SELECT COUNT(*)
FROM [UploadPackage] [up]
INNER JOIN [RawClip] [rc] on [up].[Id] = [rc].[PackageId]
WHERE [up].[UserId] IN (1,2,3)

我尝试了以下方法:

选项 1:

DbContext.UploadPackages.Include(up => up.Clips).Where(up => userIds.Contains(up.UserId)).SelectMany(u => u.Clips).CountAsync()

选项 2:

DbContext.RawClips.Include(rc => rc.Package).Where(rc => userIds.Contains(rc.Package.UserId)).CountAsync()

使用 Fluent API 配置关系,如下所示:

modelBuilder.Entity<UploadPackage>().HasMany(up => up.Clips).WithOne(rc => rc.Package);
modelBuilder.Entity<RawClip>().HasOne(rc => rc.Package).WithMany(up => up.Clips);

选项 1 生成以下 SQL:

SELECT [up].[Id], [up].[AssetId], [up].[FileName], [up].[FileSize], [up].[PackageId], [up].[Path], [up].[ProxyUrl], [up].[StatusDetails], [up].[StatusId], [up].[ThumbnailUrl], [up].[UploadCompletedDateTime], [up].[UploadStartedDateTime], [r].[Id], [r].[AssetId], [r].[FileName], [r].[FileSize], [r].[PackageId], [r].[Path], [r].[ProxyUrl], [r].[StatusDetails], [r].[StatusId], [r].[ThumbnailUrl], [r].[UploadCompletedDateTime], [r].[UploadStartedDateTime], [up].[Id]
FROM [RawClip] AS [up]
CROSS JOIN [RawClip] AS [r]
WHERE [up].[UserId] IN (2, 3, 4, 1)

如您所见,它将 RawClip 表连接到自身。在联接的一侧,它为表提供了别名“[up]”,这似乎是对 UploadPackage 的引用,即使它的别名表实际上是 RawClip 表。这最终会引发错误,因为 where 子句试图过滤“[up].[UserId]”列,该列存在于 UploadPackage 表中,但不存在于 RawClip 表中。

选项 2 失败,没有生成任何 SQL。这是堆栈跟踪的错误:

InvalidOperationException: Sequence contains more than one element
System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
Microsoft.Data.Entity.Query.EntityQueryModelVisitor.<>c__DisplayClass79_0`1.<BindMemberExpression>b__0(IEnumerable`1 ps, IQuerySource qs)
Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpressionCore[TResult](MemberExpression memberExpression, IQuerySource querySource, Func`3 memberBinder)
Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpression[TResult](MemberExpression memberExpression, IQuerySource querySource, Func`3 memberBinder)
Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpression(MemberExpression memberExpression, Action`2 memberBinder)
Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.RequiresMaterializationExpressionVisitor.VisitMember(MemberExpression memberExpression)
System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
Remotion.Linq.Clauses.ResultOperators.ContainsResultOperator.TransformExpressions(Func`2 transformation)
Remotion.Linq.QueryModel.TransformExpressions(Func`2 transformation)
Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.RequiresMaterializationExpressionVisitor.VisitSubQuery(SubQueryExpression subQueryExpression)
Remotion.Linq.Clauses.Expressions.SubQueryExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
2000 
Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
Remotion.Linq.Clauses.WhereClause.TransformExpressions(Func`2 transformation)
Remotion.Linq.QueryModel.TransformExpressions(Func`2 transformation)
Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.RequiresMaterializationExpressionVisitor.FindQuerySourcesRequiringMaterialization(QueryModel queryModel)
Microsoft.Data.Entity.Query.QueryCompilationContext.FindQuerySourcesRequiringMaterialization(EntityQueryModelVisitor queryModelVisitor, QueryModel queryModel)
Microsoft.Data.Entity.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
Microsoft.Data.Entity.Storage.Database.CompileAsyncQuery[TResult](QueryModel queryModel)
Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass19_0`1.<CompileAsyncQuery>b__0()
Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func`1 compiler)
Microsoft.Data.Entity.Query.Internal.QueryCompiler.CompileAsyncQuery[TResult](Expression query)
Microsoft.Data.Entity.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
Microsoft.Data.Entity.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
Microsoft.Data.Entity.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
Microsoft.Data.Entity.EntityFrameworkQueryableExtensions.CountAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

我做错了吗?有没有更好的方法来实现我想要做的事情?这似乎是一个相当简单的用例,所以我想必须有某种方法来完成这项工作......

【问题讨论】:

  • 你可以试试这个:DbContext.UploadPackages.Where(up => userIds.Contains(up.UserId)).SelectMany(u => u.Clips).CountAsync();如果你急切地说你想要什么导航属性,你不应该包括
  • 我不会再花时间在 RC1 上了。自 RC1(11 月)以来,已修复了许多错误。 RC2-final 现已推出。请参阅:blogs.msdn.microsoft.com/webdev/2016/05/16/… 几个月前我已经更新到 RC2 nightly builds,因为 RC1 即使是简单的连接查询也有太多错误。
  • @noox 是的,你完全正确。 EF GitHub 上的人最终也说了同样的话。 RC2 解决了这个问题。

标签: c# sql-server entity-framework entity-framework-core


【解决方案1】:

我最终收到了关于我在 EF Core GitHub 上发布的问题的回复:

https://github.com/aspnet/EntityFramework/issues/5413

此问题是 RC1 中的错误,现已在 RC2 中修复。我已经迁移到 RC2,现在一切正常。

【讨论】:

    【解决方案2】:

    试试这个:

    DbContext.UploadPackages.Where(up => userIds.Contains(up.UserId)).SelectMany(u => u.Clips).CountAsync();
    

    如果你急切地说你想要什么导航属性,你不应该包括

    【讨论】:

    • 这生成了与我原来帖子中的选项 1 相同的 SQL。
    猜你喜欢
    • 2021-10-20
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2020-01-04
    • 1970-01-01
    相关资源
    最近更新 更多