c# - 将组合键与 Entity Framework Core 一起使用并将其中的一部分用作外键
问题描述
我正在尝试制作几个具有复合键的表(下面的示例)。我已经能够使用代码优先的方法来实现这一点,但我希望这些复合键能够级联到子表。这个想法是每个子实体将具有与其父实体相同的复合键,再加上一列。
| PurchaseOrder |
| ------------- |
| Company (PK) |
| PONum (PK) |
| PuchaseOrderLine |
| ---------------- |
| Company (PK/FK) |
| PONum (PK/FK) |
| POLine (PK) |
从技术上讲,PurchaseOrder 表会与公司表做类似的事情,但这对我来说不太重要,我认为如果我能够弄清楚 POLine 到 PO 的连接,我也会弄清楚这一点。
这是我迄今为止的尝试:
// OnModelCreating method in my class that inherits IdentityDbContext<IdentityUser>
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Company>()
.DefaultConfigure(c => new { c.Name });
builder.Entity<PurchaseOrder>()
.DefaultConfigure(p => new { p.Company, p.PONum })
.HasMany(e => e.PurchaseOrderLines)
.WithOne(e => e.PurchaseOrder);
builder.Entity<PurchaseOrderLine>()
.DefaultConfigure(p => new { p.Company, p.PONum, p.LineNum })
.HasOne(e => e.PurchaseOrder)
.WithMany(e => e.PurchaseOrderLines);
}
// My DefaultConfigure extension method
public static EntityTypeBuilder<T> DefaultConfigure<T>(this EntityTypeBuilder<T> builder, Expression<Func<T, object>> keyExpression)
where T : AuditableEntity
{
// Rename table to the types name
builder.ToTable(typeof(T).Name.ToLower());
// Configure the keys they passed in
builder.HasKey(keyExpression);
// Configure the default alternate key
builder.HasAlternateKey(i => new { i.RowId });
// Give the builder back
return builder;
}
当我运行此迁移并更新我的数据库时,这就是我的 PurchaseOrderLine 表上的内容:
| COLUMN_NAME | CONSTRAINT_NAME |
| -------------------- | -------------------------------------------------------------------------- |
| RowId | AK_PurchaseOrderLine_RowId |
| PurchaseOrderCompany | FK_PurchaseOrderLine_PurchaseOrder_PurchaseOrderCompany_PurchaseOrderPONum |
| PurchaseOrderPONum | FK_PurchaseOrderLine_PurchaseOrder_PurchaseOrderCompany_PurchaseOrderPONum |
| Company | PK_PurchaseOrderLine |
| LineNum | PK_PurchaseOrderLine |
| PONum | PK_PurchaseOrderLine |
EFCore 刚刚使用默认命名方案添加了两个新列,并没有使用我已有的列。反正有没有让 efcore 使用代码优先的方法来做这样的事情?
解决方案
回答你的具体问题
反正有没有让 efcore 使用代码优先的方法来做这样的事情?
当然有。只是传统的外键名称显然不起作用,因此您必须显式配置 FK 属性(通过HasForeignKey
fluent API)。
例如,要么
builder.Entity<PurchaseOrderLine>()
.DefaultConfigure(p => new { p.Company, p.PONum, p.LineNum })
.HasOne(e => e.PurchaseOrder)
.WithMany(e => e.PurchaseOrderLines)
.HasForeignKey(e => { e.Company, e.PONum }); // <--
或者
builder.Entity<PurchaseOrder>()
.DefaultConfigure(p => new { p.Company, p.PONum })
.HasMany(e => e.PurchaseOrderLines)
.WithOne(e => e.PurchaseOrder)
.HasForeignKey(e => { e.Company, e.PONum }); // <--
请注意,两个Has
/With
对都代表一个相同的关系,因此最好只在一个地方进行,以避免配置冲突。
推荐阅读
- html - CSS 网格尺寸和对齐方式
- python - 我的 pyglet 应用程序无法显示其他幻灯片
- python - 正则表达式获取一个子字符串,其中主字符串的结尾也是子字符串的 enging
- wai-aria - 屏幕阅读器是否应该在 HTML 中的下拉菜单(或组合框)展开时通知
- javascript - ajax调用时如何从php文件中执行代码
- python - 在python中列出它们时拆分为字母的单词
- r - 在数据框中创建类型列
- azure-ad-b2c - Azure AD B2C 可以联合到基于 SAML 的 IDP 吗?
- python - 使用python请求下载并保存CSV
- python - 高级模板匹配