【发布时间】:2017-05-01 07:42:08
【问题描述】:
所以我正在深入研究 EF Core 并尝试继承和 TPH 模式(我之前没有这方面的经验)。 EF 创建的结果数据库不是我所期望的,我想知道是否有可能使用 fluent-api 获得我正在寻找的结果,或者我是否完全错过了这一点。
首先,这是我的 POCO 课程:
public class Commission
{
public int Id { get; set; }
public string Description { get; set; }
public double Rate { get; set; }
}
public class Party
{
public int PartyId { get; set; }
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
public class Agency : Party
{
public string AgencyCode { get; set; }
public ICollection<Commission> Commissions { get; set; }
}
public class Carrier : Party
{
public string CarrierCode { get; set; }
public ICollection<Commission> Commissions { get; set; }
}
public class Principal : Party
{
public string Website { get; set; }
public string DistrictCode { get; set; }
}
还有我的上下文类以防万一:
public class PartyContext : DbContext
{
public DbSet<Agency> Agencies { get; set; }
public DbSet<Carrier> Carriers { get; set; }
public DbSet<Party> Parties { get; set; }
public DbSet<Commission> Commissions { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=LAPTOP-PC\SQLEXPRESS;Database=MyDatabase;Trusted_Connection=True;");
}
}
基本上,Agency、Carrier 和 Principal 都继承自 Party,因此它们应该具有与 Party 相同的所有属性。 Agency 和 Carrier 具有额外的特定属性,并且应该与 Commissions 具有零或一对多的关系。此外,Principal 有几个特定属性,但与佣金无关。
我对 Party 表本身的输出没有任何疑问,并且了解鉴别器字段是什么,但是我不了解它创建的两个外键关系:
- 委托方_AgencyPartyId
- 佣金方_CarrierPartyId
我的问题是为什么我不能只在后端拥有一个从 Party 到 Commissions_PartyId 的外键关系?如果可以,我如何告诉 EF 以这种方式创建它?
编辑
使用 Dmitry 的建议并使用 [InverseProperty] 属性,我最终得到了以下数据库设计,这不是所需的输出:
它实际上做了第三个字段(PartyId1)。所以我再次开始查看 EF documentation on relationships 并开始使用不同的注释。使用 [ForeignKey("PartyId")] 属性给了我一些希望,因为它产生了我所期待的设计:
不过,这也产生了一些意想不到的效果。在尝试使用代理商和运营商填充数据库后,我收到了异常。
这是填充代码:
PartyContext _context = new PartyContext();
// Add an Agency
var agencyCommission1 = new Commission
{
Description = "Contract",
Rate = 0.075
};
var agencyCcommission2 = new Commission
{
Description = "Hauling",
Rate = 0.10
};
var agencyCommissionList = new List<Commission>
{
agencyCommission1, agencyCcommission2
};
var agency = new Agency
{
Name = "Agency International",
Address1 = "12345 Main Street",
Address2 = "Suite 100",
City = "Chicago",
State = "IL",
Zip = "31202",
AgencyCode = "AI",
Commissions = agencyCommissionList
};
// Add Carrier
var carrierCommission1 = new Commission
{
Description = "Coal",
Rate = 0.15
};
var carrierCommission2 = new Commission
{
Description = "Mining",
Rate = 0.115
};
var carrierCommissionList = new List<Commission>
{
carrierCommission1, carrierCommission2
};
var carrier = new Carrier
{
Name = "Carrier International",
Address1 = "54321 Main Street",
Address2 = "Suite 300",
City = "Cleveland",
State = "OH",
Zip = "44115",
CarrierCode = "CI",
Commissions = carrierCommissionList
};
_context.Agencies.Add(agency);
_context.Carriers.Add(carrier);
try
{
_context.SaveChanges();
}
catch(Exception ex)
{
return;
}
添加代理时的异常是“无法将'EFTest.Agency'类型的对象转换为'EFTest.Carrier'类型。”尝试添加运营商时的异常是“无法将'EFTest.Carrier'类型的对象转换为'EFTest.Agency'类型。”
我要补充一点,当使用原始 EF 设计时,程序确实可以按预期运行,但是额外的字段和外键让我的强迫症有点疯狂:) 欢迎更多想法!
【问题讨论】:
标签: c# entity-framework inheritance entity-framework-core