2

在我的域模型中,我有一个Company抽象的基类和由 Company 的子类表示的三种不同的 Company 类型:

public abstract class Company
{
    public int Id { get; set; }
    ...
}

public class Supplier : Company
{
    ...
}

public class Dealer : Company
{
    public DealerFundsAccount FundsAccount { get; set; }
    ...
}

public class Retailer : Company
{
    public RetailerFundsAccount FundsAccount { get; set; }
    ...
}

同样,我还有另一个基类,它定义了 Funds Account 和两个实现特定属性的子类型:

public abstract class FundsAccount
{
    public int Id { get; set; }
    ...
}

public class DealerFundsAccount : FundsAccount
{
    public Dealer Dealer { get; set; }
    ...
}

public class RetailerFundsAccount : FundsAccount
{
    public Retailer Retailer { get; set; }
    ...
}

我对这些类型的映射策略是逐层表,因此在我的 DbContext 类中,我只为基类定义 DbSet,这使我能够执行多态和非多态查询:

public DbSet<Company> Companies { get; set; }
public DbSet<FundsAccount> FundsAccounts { get; set; }

现在是棘手的部分,我的要求是:

  • 供应商不得有资金账户
  • 经销商必须有一个 DealerFundsAccount
  • 零售商必须有一个 RetailerFundsAccount

应该很简单:

modelBuilder.Entity<Retailer>()
    .HasRequired(r => r.FundsAccount)
    .WithRequiredDependent(rfa => rfa.Retailer);

modelBuilder.Entity<Dealer>()
    .HasRequired(d => d.FundsAccount)
    .WithRequiredDependent(dfa => dfa.Retailer);

但是 EF Migrations 在尝试更新数据库架构时惨遭失败。由于 TPH,Dealers 和 Retailers 映射到同一个 Company 数据库表,而 RetailerFundsAccounts 和 DealerFundsAccounts 映射到 FundsAccount db 表,所有这些都是需要的,但由于我在子类型之间定义了两个一对一的关系,EF尝试定义 FundsAccount Id 字段的外键两次

我知道我可以通过为每个具有资金帐户的 Company 表定义一对多关系来破解解决方案,并使用其 FK 中的唯一约束来防止一对多行为,但我想与你核实一下有一个更好的解决方案。

4

1 回答 1

0

事实证明,EF 迁移是罪魁祸首。如果我尝试从头开始创建数据库架构,一切都很好,但如果您创建迁移以添加这些实体,EF 会通过尝试创建索引和外键两次而失败,如下所示:

        CreateTable(
            "dbo.FundsAccount",
            c => new
                {
                    Id = c.Int(nullable: false),
                    Discriminator = c.String(nullable: false, maxLength: 128),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Company", t => t.Id)
            .ForeignKey("dbo.Company", t => t.Id) // duplicate
            .Index(t => t.Id)
            .Index(t => t.Id); // duplicate

解决方案是编辑迁移,删除重复的 FK 和索引条目。

我还将更新问题的标题以更好地描述问题。

于 2013-10-28T13:36:36.233 回答