我正在尝试使用IBM Db2
将表从旧的EntityFramework Core 2.2
数据库映射到实体,但是这些表根本没有任何键(是的,我也很震惊),而且我不确定是否甚至允许将它们添加到自石器时代以来就一直在运行的古老的野兽中。
到目前为止,我已经通过对关系进行反向工程并找到潜在的键来使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()
时,此方法有效,在我的测试代码中,我应该为一个SellerAccountDetails
获得3个Finvoice
实体,但是如果我不实现IQueryable
,我得到6 SellerAccountDetails
等于1 Finvoice
,如果再次枚举,它们会增加到9,依此类推...
EF不能从SellerAccountDetails
上配置的主键中知道什么使这个实体唯一吗?
我添加了HasPrincipalKey
,因为属性SellerPartyIdentifier
(来自Finvoice)对应于帐户表中的属性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();
谢谢!
在Db2中没有键/关系的情况下,您不能使用“包含” linq。
您必须在下面使用
var invoices = (from a in _dbContext.Invoices.Where(x => x.FinvoiceBatchNumber == 13491)
from b in _dbContext.SellersAccountDetails.Where(x => x.InvoiceId = a.Id).DefaultOrEmpty()
select a, b).Take(1);