Skip to content

Instantly share code, notes, and snippets.

@joakimriedel
Created October 11, 2018 08:29
Show Gist options
  • Save joakimriedel/b48ea98f71896cd00752c5d16bdc947a to your computer and use it in GitHub Desktop.
Save joakimriedel/b48ea98f71896cd00752c5d16bdc947a to your computer and use it in GitHub Desktop.
SelectMany with TPH and OfType throws System.ArgumentException
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace EfCoreBugSelectMany
{
class Program
{
static async Task Main(string[] args)
{
using (var context = new ClientContext())
{
//context.Database.EnsureDeleted();
context.Database.EnsureCreated();
// this query works
var carsFromOffers = await context.Offers
.OfType<CarOffer>()
.Where(o => o.CompanyId == 1)
.Select(o => o.Car)
.ToListAsync();
// this throws an exception
// Property 'Car Car' is not defined for type 'EfCoreBugSelectMany.Program+Offer'
var carsFromCompanies = await context.Companies
.Where(c => c.Id == 1)
.SelectMany(c => c.Offers.OfType<CarOffer>().Select(o => o.Car))
.ToListAsync();
}
}
public class Company
{
public int Id { get; set; }
// Navigation properties
public ICollection<Offer> Offers { get; set; }
}
public abstract class Offer
{
public int Id { get; set; }
[Required]
public Company Company { get; set; }
public int CompanyId { get; set; }
}
public class CarOffer : Offer
{
[Required]
public Car Car { get; set; }
public int CarId { get; set; }
}
public class BoatOffer : Offer
{
[Required]
public Boat Boat { get; set; }
public int BoatId { get; set; }
}
public class Car
{
public int Id { get; set; }
}
public class Boat
{
public int Id { get; set; }
}
class ClientContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// TO USE SQL
//optionsBuilder
// .UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=EfCoreBugSelectMany;Trusted_Connection=True;MultipleActiveResultSets=true;Connect Timeout=30")
// .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
// TO USE INMEMORY
optionsBuilder
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Company>().HasData(new Company
{
Id = 1
});
builder.Entity<Car>().HasData(new Car
{
Id = 1
});
builder.Entity<CarOffer>().HasData(new CarOffer
{
Id = 1,
CompanyId = 1,
CarId = 1
});
}
public DbSet<Company> Companies { get; set; }
public DbSet<Offer> Offers { get; set; }
public DbSet<CarOffer> CarOffers { get; set; }
public DbSet<BoatOffer> BoatOffers { get; set; }
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.3" />
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment