【发布时间】:2020-06-12 18:05:53
【问题描述】:
我正在尝试使用 EntityFramework Core 2.2 将旧的 IBM Db2 数据库中的表映射到实体,但这些表根本没有任何键(是的,我也很震惊)而且我不确定我是否'我什至允许将它们添加到这个从石器时代就开始运行的古老野兽中。
到目前为止,我已经通过对关系进行逆向工程并找到要使用的潜在键来完成工作,以便 EF 可以愉快地跟踪这些实体,但我面临着一对多映射的问题。
我想进行从Invoice 表到SellerAccountDetails 表的一对多映射。我的配置:
发票实体:
public class FinvoiceConfiguration : IEntityTypeConfiguration<Finvoice>
{
public void Configure(EntityTypeBuilder<Finvoice> builder)
{
// PK for Invoice
builder.HasKey(f => new { f.FinvoiceBatchNumber, f.FinvoiceBatchRowNumber });
// One-to-many to SellerAccountDetails table
builder.HasMany(f => f.SellersAccountDetails)
.WithOne(s => s.Invoice)
.HasForeignKey(s => new
{
s.FinvoiceBatchNumber,
s.FinvoiceBatchRowNumber,
s.SellerAccountPartyIdentifier
})
.HasPrincipalKey(f => new
{
f.FinvoiceBatchNumber,
f.FinvoiceBatchRowNumber,
f.SellerPartyIdentifier
});
}
}
SellerAccountDetails 实体:
public class SellerAccountDetailsConfiguration : IEntityTypeConfiguration<SellerAccountDetails>
{
public void Configure(EntityTypeBuilder<SellerAccountDetails> builder)
{
// PK for SellerAccountDetails
builder.HasKey(s => new
{
s.FinvoiceBatchNumber,
s.FinvoiceBatchRowNumber,
s.SellerAccountPartyIdentifier,
s.SellerAccountID // <-- Needed for uniqueness of this entity
});
// Many-to-one to Invoice table
builder.HasOne(s => s.Invoice)
.WithMany(i => i.SellersAccountDetails)
.HasForeignKey(s => new
{
s.FinvoiceBatchNumber,
s.FinvoiceBatchRowNumber,
s.SellerAccountPartyIdentifier
})
.HasPrincipalKey(f => new
{
f.FinvoiceBatchNumber,
f.FinvoiceBatchRowNumber,
f.SellerPartyIdentifier
});
}
}
现在,当我进行查询然后调用 ToList() 时,这可以工作,在我的测试代码中,我应该为一个 Finvoice 获得 3 个 SellerAccountDetails 实体,但如果我没有实现 IQueryable ,我得到 6 个SellerAccountDetails 一个Finvoice,如果我再次枚举,它们会增加到 9,依此类推......
EF 不应该从 SellerAccountDetails 上配置的主键中知道是什么让这个实体独一无二?
我添加了HasPrincipalKey,因为属性SellerPartyIdentifier(来自Finvoice)对应于accounts 表中的属性SellerAccountPartyIdentifier,但它不是主键。如果我删除它并只保留 2 个外键,结果是一样的。
我该如何进行这项工作?我可能在这里遗漏了一些明显的东西,但我没有看到。
这是我的示例查询:
var invoices = _dbContext.Invoices.Include(i => i.SellersAccountDetails).ThenInclude(s => s.Invoice).
Where(i => i.FinvoiceBatchNumber == 13491).OrderBy(i => i.FinvoiceBatchRowNumber).Take(1);//.ToList();
谢谢!
【问题讨论】:
标签: c# .net-core db2 entity-framework-core ef-code-first