M:M映射 - EF 4.3 CodeFirst(现有数据库)

时间:2012-03-29 15:00:10

标签: entity-framework insert many-to-many jointable payload

我有两个表(表A,表B)与一个带有3个有效负载列的连接表(TableAB)连接在一起。 By Payload我指的是除Id,TableAId和TableBId之外的列。

我可以成功插入所有表,但是我需要将数据插入到Insert上的一个有效负载列中。我正在使用EF 4.3,Fluent API。有人可以帮忙吗?提前谢谢。

    public class Organisation : EntityBase<int>, IAggregateRoot
       {
    public string Name { get; set; }
    public string Url { get; set; }
    public int CountryId { get; set; }
    public int? OwnershipTypeId { get; set; }
    public int OrganisationStatusId { get; set; }

    public virtual ICollection<Feature> Features { get; set; }
    public virtual ICollection<OrganisationType> OrganisationTypes { get; set; }
    public virtual ICollection<PricePlan> PricePlans { get; set; }
    public virtual ICollection<User> Users { get; set; }

}

    public class User: EntityBase<Guid>, IAggregateRoot
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string JobTitle { get; set; }
    public int?  PhoneCallingCodeId       { get; set; }
    public int?  PhoneAreaCode{ get; set; }
    public string PhoneLocal { get; set; }
    public int? MobileCallingCodeId { get; set; }
    public int? MobileAreaCode { get; set; }
    public string MobileLocal { get; set; }      

    public virtual ICollection<Organisation.Organisation> Organisations { get; set; }

}

   public class OrganisationUser : EntityBase<int>, IAggregateRoot
{
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public int OrganisationRoleId {get; set;}//Foreign Key - have tried leaving it out, tried it as public virtual Organisation Organisation {get;set;
    public bool IsApproved { get; set; }
}

     public class SDContext : DbContext 
{      

    public ObjectContext Core
    {
        get
        {
            return (this as IObjectContextAdapter).ObjectContext;
        }
    }
  public IDbSet<User> User { get; set; }

  public IDbSet<Organisation> Organisation { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Organisation>().HasMany(u => u.Users).WithMany(o => o.Organisations).Map(m =>
        {
            m.MapLeftKey("OrganisationId");
            m.MapRightKey("UserId");
            m.ToTable("OrganisationUser");
        });

//我试过用流利的方式专门定义外键,但是我真的需要了解一旦访问和编辑它们后如何添加有效负载属性。

1 个答案:

答案 0 :(得分:2)

您的映射不适合您的目的。如果您希望将OrganisationUser视为OrganisationUser之间的中间实体,则必须在OrganisationOrganisationUser之间以及User之间创建关系。 OrganisationUser,而不是直接位于OrganisationUser之间。

由于中间实体包含自己的标量属性,因此无法创建多对多映射。 EF不支持与“有效负载”的多对多关系。你需要两个一对多的关系:

public class Organisation : EntityBase<int>, IAggregateRoot
{
    // ...
    // this replaces the Users collection
    public virtual ICollection<OrganisationUser> OrganisationUsers { get; set; }
}

public class User : EntityBase<Guid>, IAggregateRoot
{
    // ...
    // this replaces the Organisations collection
    public virtual ICollection<OrganisationUser> OrganisationUsers { get; set; }
}

public class OrganisationUser : EntityBase<int>, IAggregateRoot
{
    public int OrganisationId { get; set; }
    public Organisation Organisation { get; set; }

    public Guid UserId { get; set; }
    public User User { get; set; }

    // ... "payload" properties ...
}

在Fluent API中,您必须通过以下内容替换多对多映射:

modelBuilder.Entity<Organisation>()
    .HasMany(o => o.OrganisationUsers)
    .WithRequired(ou => ou.Organisation)
    .HasForeignKey(ou => ou.OrganisationId);

modelBuilder.Entity<User>()
    .HasMany(u => u.OrganisationUsers)
    .WithRequired(ou => ou.User)
    .HasForeignKey(ou => ou.UserId);

您的派生DbContext也可能包含OrganisationUser实体的单独集:

public IDbSet<OrganisationUser> OrganisationUsers { get; set; }

现在很明显你如何在中间表中写一些东西:

var newOrganisationUser = new OrganisastionUser
{
    OrganisationId = 5,
    UserId = 8,
    SomePayLoadProperty = someValue,
    // ...
};

context.OrganisastionUsers.Add(newOrganisastionUser);
context.SaveChanges();

如果要确保每对OrganisationIdUserId只能在链接表中存在一次,那么最好为这两列创建复合主键以确保唯一性在数据库中而不是使用单独的Id。在Fluent API中,它将是:

modelBuilder.Entity<OrganisationUser>()
    .HasKey(ou => new { ou.OrganisationId, ou.UserId });

有关此类型号以及如何使用它的更多详细信息,请访问:

Create code first, many to many, with additional fields in association table