【问题标题】:EntityFramework inheritance using existent base class instance使用现有基类实例的实体框架继承
【发布时间】:2014-07-29 13:02:42
【问题描述】:

我在我的模型中使用 TPT 策略。

以下是我的上下文:

public class MyTestContext : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public DbSet<Seller> Sellers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Entity<Person>().ToTable("Persons");
        modelBuilder.Entity<Seller>().ToTable("Sellers");
        base.OnModelCreating(modelBuilder);
    }
}

这里是我的实体:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Seller : Person
{
    public decimal Comissao { get; set; }
}

我正在尝试重用一个已经存在的数据库寄存器。 我有 2 个 CRUD,一个用于 Person,另一个用于 Seller。

场景:

我的数据库中有 10 个人和 0 个卖家,就像这个种子:

using (var ctx = new MyTestContext())
{
    Func<int, Person> selector = i => new Person
    {
        Name = string.Format("Person {0}", i)
    };
    var persons = Enumerable.Range(1, 10).Select(selector);
    ctx.Persons.AddRange(persons);

    ctx.SaveChanges();
}

我想添加新的卖家,但我想重用数据库中已经存在的人:

using (var ctx = new MyTestContext())
{
    var seller = new Seller { Id = 1, Comissao = 10 };
    ctx.Sellers.Add(seller);

    ctx.SaveChanges();
}

当 Entity Framework 保存时,他创建了一个新的 Person 和一个新的 Seller。

如何使用继承策略并能够使用我在 Seller 中分配的 Id 来创建一个新的 Person 并使用这个新 Id?

【问题讨论】:

    标签: c# entity-framework ef-code-first table-per-type


    【解决方案1】:

    您不能将 TPT 用于一对一或零关系。

    因为能够有一对一或零的关系。您需要在Person 上拥有Seller 属性,在Seller 上拥有Person 属性。

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Seller Seller { get; set; }
    }
    public class Seller : Person
    {
        public decimal Comissao { get; set; }
        public Person Person { get; set; }
    }
    

    但是上面的代码不起作用,因为Person上的Seller属性也会被继承到Seller,它会被认为是另一个关系。

    解决方案

    • 有另一个名为BasePerson 的抽象类
    • PersonSeller 都派生自 BasePerson
    • 使用每个具体类映射的表

    这里是类

    public abstract class BasePerson
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    public class Person : BasePerson
    {
        public Seller Seller { get; set; }
    }
    public class Seller : BasePerson
    {
        public decimal Comissao { get; set; }
        public Person Person { get; set; }
    }    
    public class AppContext : DbContext
    {
        public DbSet<Person> People { get; set; }
        public DbSet<Seller> Sellers { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Configures one to one-or-zero relationship.
            modelBuilder.Entity<Seller>().HasRequired(x => x.Person).WithRequiredDependent(x => x.Seller);
        }
    }
    

    示例用法

    using (var context = new AppContext())
    {
        context.People.Add(new Person { Id = 1 });
        context.SaveChanges();
    }
    using (var context = new AppContext())
    {
        context.Sellers.Add(new Seller { Id = 1 });
        context.SaveChanges();
    }
    using (var context = new AppContext())
    {
        // Throws DBUpdateException, Person Id = 2 doesn't exist.
        context.Sellers.Add(new Seller { Id = 2 });
        context.SaveChanges();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-19
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多