EF代码第一个多对多,主键由3个字段组成

时间:2013-01-08 12:16:13

标签: c# entity-framework ef-code-first

我正在使用EF5(Code 1st)并使用Fluent API完成所有配置。我的模型看起来像这样:

public class AddressType    
{
    public int    AddressTypeID { get; set; }
    public string Name          { get; set; }
}
public class Address
{
    public int    AddressID  { get; set; }
    public int    StateID    { get; set; }

    public string Street     { get; set; }
    public string City       { get; set; }
    public string PostalCode { get; set; }

    public State State                { get; set; }
    public ICollection<Person> People { get; set; }
}
public class Person
{
    public int      PersonID    { get; set; }
    public string   Name        { get; set; }

    public ICollection<Address> Addresses { get; set; }
}

我的数据库包含上述类的表+下面的许多:许多表:

Person.Person2Address
(
    PersonID      INT NOT NULL,
    AddressID     INT NOT NULL,
    AddressTypeID INT NOT NULL,
)

上面的3个字段都是外键&amp; 3一起构成了表的主键。

通常我的M:M设置只涉及PK中的2个字段。我会像这样映射它:

var addressCfg = mb.Entity<Address>();
addressCfg.ToTable("Address", "Geo");
addressCfg.HasMany(a => a.People)
          .WithMany(p => p.Addresses)
          .Map(mmc =>
          {
             mmc.ToTable("Person2Address", "Person");
             mmc.MapLeftKey("AddressID");
             mmc.MapRightKey("PersonID");
          });

但我不知道如何在PK中配置第3个字段,或者在这种情况下CRUD如何在EF中工作。

非常感谢任何有关如何处理这个问题的例子。

1 个答案:

答案 0 :(得分:2)

您无法将此映射为多对多关系。您需要三个一对多关系,其中一个中间附加实体Person2Address表示具有三个键的链接表。 PersonAddress中的集合都必须引用此中间实体(以及AddressType中的集合)。

模型将是这样的:

public class AddressType
{
    public int AddressTypeID { get; set; }
    public string Name { get; set; }

    // public ICollection<Person2Address> Person2Addresses { get; set; }
    // optionally you can include this collection or not
}

public class Address
{
    public int AddressID { get; set; }
    public int StateID { get; set; }

    public string Street { get; set; }
    public string City { get; set; }
    public string PostalCode { get; set; }

    public State State { get; set; }
    public ICollection<Person2Address> Person2Addresses { get; set; }
}

public class Person
{
    public int PersonID { get; set; }
    public string Name { get; set; }

    public ICollection<Person2Address> Person2Addresses { get; set; }
}

public class Person2Address
{
    public int PersonID { get; set; }
    public int AddressID { get; set; }
    public int AddressTypeID { get; set; }

    public Person Person { get; set; }
    public Address Address { get; set; }
    public AddressType AddressType { get; set; }
}

使用Fluent API进行映射:

modelBuilder.Entity<Person2Address>()
    .HasKey(p2a => new { p2a.PersonID, p2a.AddressID, p2a.AddressTypeID });

modelBuilder.Entity<Person2Address>()
    .HasRequired(p2a => p2a.Person)
    .WithMany(p => p.Person2Addresses)
    .HasForeignKey(p2a => p2a.PersonID);

modelBuilder.Entity<Person2Address>()
    .HasRequired(p2a => p2a.Address)
    .WithMany(a => a.Person2Addresses)
    .HasForeignKey(p2a => p2a.AddressID);

modelBuilder.Entity<Person2Address>()
    .HasRequired(p2a => p2a.AddressType)
    .WithMany()
    .HasForeignKey(p2a => p2a.AddressTypeID);

如果您想在WithMany(at => at.Person2Addresses)中加入该集合,请在最后一个映射中使用AddressType

相关问题