簡體   English   中英

實體框架對使用復合主鍵的表形成虛擬 collections

[英]Entity Framework forming virtual collections to tables that use composite primary keys

在實體框架中,如何將虛擬集合鏈接到另一個使用復合鍵的表? 這是兩個示例表:

public abstract class Table1
{
    public Guid EventId { get; set; }
    public string EventName { get; set; }

    public virtual ICollection<Table2> Table2 { get; private set; }
}

public abstract class Table2
{
    public Guid EventId { get; set; }
    public string DetailKey { get; set; }
    public string DetailValue { get; set; }

    public virtual Table1 Table1 { get; set; }
}

意思是在Table1中添加一個事件,然后使用一對多的關系,向Table2添加N行。 表 1 中的 Guid EventId為 PK,表 2 中的 PK 由EventId + DetailKey組合而成,即 Table2 中可能有 N 行與 Table1 中對應的EventId相關。 Table2 也有一個EventId到 Table1 的 EventId 的 FK。

Table1 的 map 文件如下所示(部分):

public override void ConfigureImp(EntityTypeBuilder<Table1> builder)
{
    base.ConfigureImp(builder);

    // Relationships            
    builder.HasMany(t => t.Table2)
          .WithOne(t => t.Table1)
          .HasForeignKey(x => new { x.EventId, x.DetailKey });
}

Table2 的 map 文件如下所示(部分):

public override void ConfigureImp(EntityTypeBuilder<Table2> builder)
{
    base.ConfigureImp(builder);

    // Relationships
    builder.HasOne(t => t.Table1)
         .WithMany(t => t.Table2)
         .HasForeignKey(x => x.EventId)
         .OnDelete(DeleteBehavior.Restrict)
         .IsRequired();
}

讓我們添加一些數據,比如向 Table1 添加 1 行 EventId FOO ,向 Table2 添加 5 行,其中 Table2 中的每一行具有相同的 EventId(以滿足 FK)但唯一的 DetailKey(以滿足復合鍵)。 完成此操作后,我運行如下查詢:

Table1 target = db.Table1
                    .Include(x => x.Table2)
                    .SingleOrDefault(x => x.EventId.Equals("FOO"));

執行此操作並檢查target的內容(例如,作為斷點)我希望看到來自 Table1 的詳細信息,以及來自 Table2 的所有 5 行,因為.Include 但是,我實際上得到的只是 Table2 中的一行,無論哪一行先出現在表中(這意味着它可以隨着該EventId的其他行添加到 Table2 中而改變。

關於為什么我沒有使用上面針對target顯示的查詢從 Table2 中獲取所有相應行的任何想法? 謝謝你。

不需要兩次聲明關系,外鍵就是EventId。

例如


public  class Event
{
    public Guid EventId { get; set; }
    public string EventName { get; set; }

    public virtual ICollection<EventDetail> Details { get; private set; }
}
public class EventDetail
{
    public Guid EventId { get; set; }
    public string DetailKey { get; set; }
    public string DetailValue { get; set; }

    public virtual Event Event{ get; set; }
}


protected override void OnModelCreating(ModelBuilder modelBuilder)
{


     modelBuilder.Entity<EventDetail>()
         .HasOne(t => t.Event)
         .WithMany(t => t.Details)
         .HasForeignKey(x => x.EventId)
         .OnDelete(DeleteBehavior.Restrict)
         .IsRequired();

    modelBuilder.Entity<EventDetail>().HasKey(e => new { e.EventId, e.DetailKey });

    base.OnModelCreating(modelBuilder);
}

你可以只添加必要的屬性,你應該能夠避免你寫的方法:

public  class Event
{
    [Key]
    public virtual Guid EventId { get; set; }
    public virtual string EventName { get; set; }
    public virtual ICollection<EventDetail> Details { get; set; }
}
public class EventDetail
{
    [Key, Column(Order = 0)]
    [ForeignKey("EventId")]
    public virtual Guid EventId { get; set; }
    [Key, Column(Order = 1)]
    public virtual string DetailKey { get; set; }
    public virtual string DetailValue { get; set; }
    public virtual Event Event{ get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM