简体   繁体   English

首先使用实体​​框架代码与联结表一对多关系

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

I'm creating a database using EF6 code first, and am struggling to create a one-to-many relationship using a junction table. 我首先使用EF6代码创建数据库,并努力使用联结表创建一对多关系。

Here's an example of what I'm trying to do: 这是我要执行的操作的一个示例:

Foo entities can contain any number (0-n) of Bar entities, however Bar entities don't necessarily belong to a Foo . Foo实体可以包含任意数量(0-n)的Bar实体,但是Bar实体不一定属于Foo I may want a different type of entity to also contain one or more Bar , so it's important that Bar doesn't contain its parent's foreign key. 我可能希望其他类型的实体也包含一个或多个Bar ,因此Bar不包含其父级的外键很重要。

So the join table would be like so: 因此,联接表将如下所示:

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

So if we create the entities as follows: 因此,如果我们按如下方式创建实体:

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

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

And then configure them: 然后配置它们:

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

But this results in the following exception being thrown: 但这导致抛出以下异常:

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.

Unfortunately I'm not sure what this means - do I need to create a seperate FooBar entity? 不幸的是,我不确定这意味着什么-我需要创建一个单独的FooBar实体吗?

How can I configure these entities so that the join table is correctly created? 如何配置这些实体,以便正确创建联接表?

Thanks! 谢谢!

Sorry to resurrect this thread, but I wanted to share a utility I created to handle a WebApi that had many instances of this same kind of relationship. 很抱歉要重新启用此线程,但是我想共享一个我创建的用于处理WebApi的实用程序,该实用程序具有许多这种类型的关系实例。 We have multiple business objects which each have relationships to EventHistory, Messages, Files, etc, and it was messy keeping track of all the FluentAPI functions. 我们有多个业务对象,每个业务对象都与EventHistory,Messages,Files等相关,并且混乱地跟踪所有FluentAPI函数。 Here's what I came up with: 这是我想出的:

    /// <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);
            });

    }

And I apply the relationship like so: 我这样应用这种关系:

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

If you do not want to store the key of foo in your bar then you have to go for a many to many relationship. 如果您不想将foo的键存储在bar则必须进行多对多关系。 The way you will make it act like a one to many relationship is up to your implementation after, there is still a way to make sure bar has only one foo , but for EF6 to make the junction table, the only way to go is many to many relationship. 使它表现为一对多关系的方式取决于您的实现,仍然有一种方法可以确保bar只有一个foo ,但是对于EF6来创建联结表,唯一的方法是许多关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架代码优先与同一数据库表一对多关系 - Entity Framework code first One to Many Relationship with same database table Entity Framework 5.0代码首先是一对一和一对多的关系 - Entity Framework 5.0 code first one to one and one to many relationship 实体框架代码在单个表中的第一个多对多关系 - Entity Framework Code First Many to Many relationship(s) in single table 实体框架代码优先在同一个表上的多对多关系 - Entity Framework Code-first Many to many relationship on the same table 实体框架代码优先的一对多表 - One table to many with Entity Framework Code First 代码优先实体框架C#,多对多映射,创建连接表,但未在对象上填充列表属性 - Code First Entity Framework C#, Many to Many Mapping, Junction Table Created but list property not populated on object 为什么首先在一对多关系实体框架代码中添加约束 - Why add a constraint in one to many relationship entity framework code first 无需代码优先模型创建的一对多关系实体框架 - One To Many relationship entity framework without Code First Model Creation 实体框架代码优先一对多关系 - Entity Framework code first one-to-many relationship Code First Entity Framework不会创建一对多关系 - Code First Entity Framework doesn't create one to many relationship
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM