2012-03-29 67 views
1

我有两个表(表A,表B)与一个有3个有效负载列的连接表(TableAB)连接。 By Payload我指的是除了Id,TableAId和TableBId以外的列。M:M映射 - EF 4.3 CodeFirst(现有数据库)

我可以成功插入到所有表中,但我需要将数据插入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

能否请你告诉你的类(尤其是他们的导航属性)和Fluent映射? – Slauma 2012-03-29 15:20:01

+0

嗨,这真的很重要吗?我知道这些表与POCO正确映射,因为ID全部插入正常。我只是不知道如何访问有效载荷列。比方说,我有一个组织,我添加用户,账单计划等,所以我很想得到相关实体,在foreach循环中使用organisation.Add(entity)将这些集合添加到我的组织中。我如何访问有效负载的连接表 - 我已经为连接创建了一个POCO类。 – user1182263 2012-03-29 18:39:42

+0

是的,这很重要,因为围绕你的问题的漫长沉默证明了这一点。由于您没有提供必要的详细信息,因此您至今没有答案。最后一句是很重要的 - 你的连接表的实体,这将有你的有效载荷列,对不对?那么问题在哪里?加载它,改变它,将它保存...您可以编辑您的问题(“编辑”链接下面的问题)来添加更多的相关信息。 – Slauma 2012-03-29 18:50:27

回答

2

您的映射对于您的目的不正确。如果你想OrganisationUser之间对待OrganisationUser作为中间实体必须创建OrganisationOrganisationUser之间和UserOrganisationUser,不能直接与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 ... 
} 

用流利的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。在流利的API将是:

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

更多关于这种类型的模型,以及如何与它合作的细节是在这里:

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

+0

感谢一家工厂!我今天会尝试。我之前读过这篇文章,但我很惊讶,现在在EF中还没有这方面的支持。非常感谢帮忙。 – user1182263 2012-03-30 06:38:24

+0

嗨,这工作。我仍然有问题,但它是因为我用它试图提供一个ID为我的身份规范列EntityBase。真的很感谢帮助。谢谢。 – user1182263 2012-03-30 14:24:11

+0

院校布局结构调整我的情况,这种情况下,我得到了错误的SQLException:外键“FK_dbo.OrganisationUser_dbo.Organisation_OrganisationId”中引用的表“dbo.Organisation”引用无效列“OrganisationId”。无法创建约束。为什么? – 2012-10-16 15:22:09