【问题标题】:System.InvalidOperationException: 'Unable to translate set operation since both operands have different 'Include' operationsSystem.InvalidOperationException: '无法翻译集合操作,因为两个操作数具有不同的 'Include' 操作
【发布时间】:2021-02-28 13:50:12
【问题描述】:

我正在使用 Entity Framework Core 5 和 Table Per Type feature。 我有Contractor 实体和两个继承的实体:CompanyIndividual。 我需要联合他们。 我正在尝试使用以下代码将它们合并到一个集合中:

    var companies = (from company in _dbContext.Companies
                      .Include(c => c.ShareHolders)
                      .Include(c => c.Director)
                      select company).Cast<Contractor>();
    var individuals = (from individual in _dbContext.Individuals
                      select individual).Cast<Contractor>();
    Contractors = new ObservableCollection<Contractor>(companies.Union(individuals));

在DBContext中我有如下配置方法:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Company>()
            .HasOne(c => c.Director);
        modelBuilder.Entity<Shareholder>()
            .HasOne(s => s.Contractor);
        modelBuilder.Entity<Company>()
            .HasMany(c => c.ShareHolders)
            .WithOne(f => f.Company)
            .OnDelete(DeleteBehavior.Cascade);
    }

问题:

如何消除异常或如何修改我的配置以便填充股东,并且我可以简单地使用 Contractors DbSet 而不是手动构建联合查询?

System.InvalidOperationException

无法转换集合操作,因为两个操作数具有不同的“包含”操作。考虑在两侧应用相同的“包含”。

堆栈跟踪:

在 Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessSetOperation(NavigationExpansionExpression outerSource, MethodInfo genericMethod, NavigationExpansionExpression innerSource)

使用 .Union() 失败。

以前我在 DbContext 中有 Contractors DbSet,但 Shareholders 集合没有填充公司对象。于是我改写了如上所示的代码。

【问题讨论】:

    标签: c# entity-framework entity-framework-core entity-framework-core-5


    【解决方案1】:

    您必须将查询除以两个查询。 Eager Loading 无法处理您首选的 UnionConcat

    简短回答原因:因为没有办法为这种情况生成 SQL。如果有相同的Includes - 这是可能的,因为 EF 可以使用 UNION 生成子查询的连接。

    Contractors = new ObservableCollection<Contractor>(
        companies.AsEnumerable()
        .Concat(individuals.AsEnumerable())
    );
    

    【讨论】:

    • 它可以工作,但看起来不太好。有什么办法可以强制承包商填充股东,避免人工工会操作?
    • 不确定我是否明白您的问题。但也许您必须将 ShareHolders 移动到 Contractor 类型?
    • 否,股东包含 2 个字段份额(百分比)和承包商。问题是。当使用 Table per type 并使用基类集合时,如何为继承的对象指定特定的包含。
    • 公司以一对多的方式与股东建立联系,特定于公司。(不适用于个人)
    • @AccessDenied,我认为没有办法。只有两个查询。 Eager Loading 是一个非常复杂的功能,它无法处理这种情况。
    【解决方案2】:

    遇到了同样的问题,似乎 EF 6 支持它,但 .NET Core 5 不支持。标题下有一个注释Table-per-type configuration 因此,您可以迁移到 EF 6 或编写 SQL 存储过程。

    您还需要检查您的 Union 操作是否联合了相同的模型。

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 1970-01-01
      • 2023-03-14
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2020-02-07
      相关资源
      最近更新 更多