簡體   English   中英

首先使用實體​​框架代碼與聯結表一對多關系

[英]One to many relationship with junction table using Entity Framework code first

我首先使用EF6代碼創建數據庫,並努力使用聯結表創建一對多關系。

這是我要執行的操作的一個示例:

Foo實體可以包含任意數量(0-n)的Bar實體,但是Bar實體不一定屬於Foo 我可能希望其他類型的實體也包含一個或多個Bar ,因此Bar不包含其父級的外鍵很重要。

因此,聯接表將如下所示:

Name        | FooBar
------------|-------
Primary Key | BarID
Key         | FooID

因此,如果我們按如下方式創建實體:

public class Foo
{
  public long ID { get; set; }
  public ICollection<Bar> Bars { get; set; }
}

public class Bar
{
  public long ID { get; set; }
}

然后配置它們:

public class FooConfiguration : EntityTypeConfiguration<Foo>
{
  HasKey(p => p.ID);
  HasMany(p => p.Bars)
    .WithRequired()
    .Map(m => {
      m.ToTable("FooBar");
      m.MapKey("FooKey");
    });
}

但這導致拋出以下異常:

An exception of type 'System.InvalidOperationException' occurred in mscorlib.dll but was not handled in user code. Additional information: The specified table 'FooBar' was not found in the model. Ensure that the table name has been correctly specified.

不幸的是,我不確定這意味着什么-我需要創建一個單獨的FooBar實體嗎?

如何配置這些實體,以便正確創建聯接表?

謝謝!

很抱歉要重新啟用此線程,但是我想共享一個我創建的用於處理WebApi的實用程序,該實用程序具有許多這種類型的關系實例。 我們有多個業務對象,每個業務對象都與EventHistory,Messages,Files等相關,並且混亂地跟蹤所有FluentAPI函數。 這是我想出的:

    /// <summary>
    /// Maps a many-to-many relationship that can only be navigated from TSource to TTarget.
    /// </summary>
    /// <typeparam name="TSource">Source type that can navigate to TTarget.</typeparam>
    /// <typeparam name="TTarget">Target type that has no direct link back to TSource.</typeparam>
    /// <param name="modelBuilder">An instance of DbModelBuilder</param>
    /// <param name="expr">Lambda expression specifying the navigation property for this relationship from TSource to TTarget.</param>
    /// <param name="leftKey">Optional argument to override the foreign key to TSource</param>
    /// <param name="rightKey">Optional argument to override the foreign key to TTarget</param>
    public static void MapDirectionalManyToMany<TSource, TTarget>(DbModelBuilder modelBuilder, Expression<Func<TSource, ICollection<TTarget>>> expr, string tableName = null, string leftKey = null, string rightKey = null)
        where TSource : class
        where TTarget : class {

        modelBuilder.Entity<TSource>()
            .HasMany(expr)
            .WithMany()
            .Map(m => {
                m.MapLeftKey(leftKey ?? typeof(TSource).Name + "Id");
                m.MapRightKey(rightKey ?? typeof(TTarget).Name + "Id");
                m.ToTable(tableName ?? typeof(TSource).Name + typeof(TTarget).Name);
            });

    }

我這樣應用這種關系:

ModelUtils.MapDirectionalManyToMany<MyResourceModel, SharedHistoryModel>(modelBuilder, x => x.History);
ModelUtils.MapDirectionalManyToMany<OtherResourceModel, SharedHistoryModel>(modelBuilder, x => x.History, "renamed_history");

如果您不想將foo的鍵存儲在bar則必須進行多對多關系。 使它表現為一對多關系的方式取決於您的實現,仍然有一種方法可以確保bar只有一個foo ,但是對於EF6來創建聯結表,唯一的方法是許多關系。

暫無
暫無

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

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