【问题标题】:EF Core one-to-many mapping to tables with no keysEF Core 一对多映射到没有键的表
【发布时间】: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


    【解决方案1】:

    您不能在 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);
    

    【讨论】:

    • 感谢您的意见,但不是这样 :)
    【解决方案2】:

    解决了!问题是实体属性的 getter 正在修剪字段:

    private string _sellerAccountID;
    
    [Column("FV77A", TypeName = "char(35)")]
    [Required, DefaultValue("")]
    [MinLength(0), MaxLength(35)]
    public string SellerAccountID
    {
        get { return _sellerAccountID.Trim(); } // <-- Trim() is the culprit
        set { _sellerAccountID = value; }
    }
    

    由于某种原因,这使 EF 跟踪器感到困惑,因为如果我还使用 AsNoTracking 禁用跟踪(或通过 optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); 全局设置它,那么它也可以正常工作。

    我删除了修剪(和私有字段),并在 DTO 级别使用 AutoMapper 进行修剪,如下所示: CreateMap&lt;string, string&gt;().ConvertUsing((s, d) =&gt; s.Trim());

    现在,无论我枚举 IQueryable 多少次,我都应该得到 3 个结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2018-07-03
      • 2023-02-23
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      相关资源
      最近更新 更多