映射多对多的关系

时间:2012-02-27 18:35:16

标签: entity-framework-4.1 ef-code-first

我在使用Entity Framework处理数据模式中的多对多关系时遇到了一些麻烦。这是我的模特:

public class User
{
    public int UserId { get; set; }
    public int Username { get; set; }
    public IEnumerable<Customer> Customers { get; set; }
    ...
}

public class Customer
{
    public int CustomerId { get; set; }
    ...
}

public class CustomerUser
{
    public int CustomerUserId { get; set; }
    public int CustomerId { get; set; }
    public int UserId { get; set; }
    public DateTime CreatedTimestamp { get; set; }
    ...
}

以下是映射:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<User>().HasKey(u => u.UserId).ToTable("Users");
        modelBuilder.Entity<Customer>().HasKey(c => c.CustomerId).ToTable("Customer");
        modelBuilder.Entity<CustomerUsers>().HasKey(cu => cu.CustomerUserId).ToTable("CustomerUsers");

        modelBuilder.Entity<CustomerUsers>()
            .HasRequired(cu => cu.User)
            .WithRequiredDependent()
            .Map(m =>
                {
                    m.ToTable("Users");
                    m.MapKey("CustomerUsers.UserId");
                });
}

我的数据库有一个Users,Customers和CustomerUsers表,其中包含与模型匹配的列。

我正在尝试执行以下查询:

result = (from u in context.Users
                      join customerUsers in context.CustomerUsers on u.UserId equals customerUsers.User.UserId
                      join customers in context.Customers on customerUsers.CustomerId equals customers.CustomerId into ps
                      select new
                      {
                          User = u,
                          Customers = ps
                      }).ToList().Select(r => { r.User.Customers = r.Customers.ToList(); return r.User; });

当我运行代码时,出现以下错误:

The Column 'CustomerUserId' specified as part of this MSL does not exist in MetadataWorkspace

有人能看出我的做法有什么问题吗?

谢谢!

我应该注意,我故意尝试不在Customer或User类中包含对CustomerUsers表的引用。大多数情况下,CustomerUsers表的有效负载并不重要,只有哪些客户与哪些用户相关联。有一些报告场景,其中连接表中的附加信息是必要的,但由于这不是典型的情况,我想通过具有这种额外的间接避免使模型混乱。

2 个答案:

答案 0 :(得分:4)

不是尝试将其映射为多对多,而是将其映射为两个到多个关系。请参阅本教程中对多对多关系中有效负载的多对多联接表的讨论:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application

答案 1 :(得分:2)

对于您的模型,您可能需要两个一对多关系和以下导航属性:

public class User
{
    public int UserId { get; set; }
    public int Username { get; set; }
    // ...
    public ICollection<CustomerUser> CustomerUsers { get; set; }
}

public class Customer
{
    public int CustomerId { get; set; }
    //...
    public ICollection<CustomerUser> CustomerUsers { get; set; }
}

public class CustomerUser
{
    public int CustomerUserId { get; set; }
    public int CustomerId { get; set; }
    public int UserId { get; set; }
    public DateTime CreatedTimestamp { get; set; }
    //...
    public User User { get; set; }
    public Customer Customer { get; set; }
}

以下映射:

modelBuilder.Entity<CustomerUser>()
    .HasRequired(cu => cu.User)
    .WithMany(u => u.CustomerUsers)
    .HasForeignKey(cu => cu.UserId);

modelBuilder.Entity<CustomerUser>()
    .HasRequired(cu => cu.Customer)
    .WithMany(c => c.CustomerUsers)
    .HasForeignKey(cu => cu.CustomerId);