0
votes

I'm using Entity Framework Core 5 and Table Per Type feature. I have Contractor entity and two inherited entities: Company and Individual. I need to union them. I'm trying the following code to union them into one collection:

    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));

In DBContext I have the following configuration method:

    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);
    }

Question:

How to get rid of the exception or how to modify my configuration so that shareholders are populated and I could simply use Contractors DbSet instead of manually building union query?

System.InvalidOperationException

Unable to translate set operation since both operands have different 'Include' operations. Consider having same 'Include' applied on both sides.

Stacktrace:

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

It fails on the line with .Union().

Previously I had Contractors DbSet in DbContext, but Shareholders collection didn't fill in for company objects. So I rewrote the code as shown above.

2

2 Answers

1
votes

You have to divide your query by two queries. Eager Loading cannot handle such Union or Concat which is preferred in your case.

Short answer why: because no way to generate SQL for such case. If there are identical Includes - it is possible because EF can generate joins to subquery with UNION.

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

got the same issue, it seems like EF 6 supports it, but not the .NET Core 5. There is a note under the title Table-per-type configuration So you can move to EF 6 or write SQL stored procedures.

Also you need to check if your Union operation unites the same models.