dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.73k stars 3.17k forks source link

Brining base type into model does not setup inheritance if key was defined on derived type #3858

Closed rowanmiller closed 2 years ago

rowanmiller commented 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; }
    }

}
rowanmiller commented 8 years ago

Closing as we now have https://github.com/aspnet/EntityFramework/issues/3860 for a more general look at base type inclusion