Closed divega closed 8 years ago
The following code results in a model where AllergenQuantity
and AllergenQuantityMaterial
are not in an inheritance hierarchy.
using Microsoft.Data.Entity;
using System;
using System.Collections.Generic;
namespace Repro
{
class Program
{
static void Main(string[] args)
{
using (var db = new MyContext())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var peanutButter = new Material { Name = "Peanut Butter" };
db.Materials.Add(peanutButter);
var peanuts = new Allergen { Name = "Peanuts" };
db.Allergens.Add(peanuts);
db.AllergenQuantityMaterials.Add(new AllergenQuantityMaterial
{
Allergen = peanuts,
Material = peanutButter,
Quantity = 1000
});
db.SaveChanges();
}
}
}
public class MyContext : DbContext
{
public DbSet<Material> Materials { get; set; }
public DbSet<Allergen> Allergens { get; set; }
public DbSet<AllergenQuantityMaterial> AllergenQuantityMaterials { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<AllergenQuantityMaterial>()
.HasKey(l => new { l.MaterialId, l.AllergenId });
modelBuilder.Entity<AllergenQuantity>().HasKey(a => a.Quantity);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Repro;Trusted_Connection=True;");
}
}
public class AllergenQuantity
{
public decimal Quantity { get; set; }
}
public class AllergenQuantityMaterial : AllergenQuantity
{
public Guid MaterialId { get; set; }
public virtual Material Material { get; set; }
public Guid AllergenId { get; set; }
public virtual Allergen Allergen { get; set; }
}
public class Material
{
public Material()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<AllergenQuantityMaterial> AllergenQuantityMaterial { get; set; }
}
public class Allergen
{
public Allergen()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<AllergenQuantityMaterial> AllergenQuantityMaterial { get; set; }
}
}
Conclusion for the moment is that we will just block having types that inherit in CLR but not in the model. This will give an exception in this case - perhaps not the clearest message, but at least you don't inadvertently get the wrong thing.
Currently it is possible to break an inheritance hierarchy by providing entity key configuration on derived types first and then conflicting configuration on a base type.
We should consider throwing an exception at conflicting key configuration regardless of the order.
@rowanmiller could you paste the repro code here?