0

我正在使用 Entity Framework Core 5 和Table Per Type 功能。我有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 集合没有填写公司对象。所以我重写了如上所示的代码。

4

2 回答 2

1

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

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

Contractors = new ObservableCollection<Contractor>(
    companies.AsEnumerable()
    .Concat(individuals.AsEnumerable())
);
于 2020-11-17T11:09:14.323 回答
0

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

此外,您还需要检查您的 Union 操作是否统一了相同的模型。

于 2021-07-19T10:45:42.180 回答