简体   繁体   中英

Entity Framework Code First Many to Many relationship(s) in single table

I've been lurking around for quite some time, so here's the first question ;)

I've been playing with Entity Framework 5.0 Code First and I want to do following:

I have two entities and I want every entity to have relation to Address entity in the following way:

  • I have one Address entity which stores address values, it doesn't have relation to entities for which it has values, instead
  • There's another entity AddressBook which has reference to Address entity and the coresponding entities ( Person , Company , some others in the future)

Here's code:

public partial class Address : BaseEntity
{
    [Key]
    public int ID { get; set; }
    public string Street { get; set; }
    public string CityName { get; set; }
    public int? PostalCode { get; set; }

    public virtual ICollection<Person> Persons { get; set; }
    public virtual ICollection<Company> Companies{ get; set; }
}

public partial class Person : BaseEntity 
{
    [Key]
    public int ID { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }

}

public partial class Company: BaseEntity 
{
    [Key]
    public int ID { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

What will this do is create database schema with tables:

  • Address
  • AddressPerson (with composite primary key)
    • Address_ID
    • Person_ID
  • AddressCompany
    • Address_ID
    • Company_ID
  • People
  • Companies

Here's what I want to do:

  • Address
  • AddressBook
    • Address_ID (PK)
    • Person_ID (FK)
    • Company_ID (FK)
  • People
  • Companies

What I want to do is have table like AddressBook :

public partial class AddressBook
{
    [Key]
    public int ID { get; set; }
    public virtual Address Address { get; set; }
    public virtual Person Person { get; set; }
    public virtual Company Company { get; set; }
}

I'm not sure how to define navigational properties in Person and Company class.

They should have ICollection<Address> Addresses navigational property, because I want them to work just with collection of addresses without knowing about underlying AddressBook .

Is it possible to do this with DbModelBuilder or should I write code inside getter and setter of ICollection<Address> Addresses property and get addresses from AddressBook ?

Thanks!

You cannot create a mapping in a way that Entity Framework would understand the Addresses collections in Person and Company as true navigation properties (which support eager and lazy loading and so on). For this you need indeed AddressBooks collections. You can add the Addresses as not mapped and readonly helper properties then:

public partial class Person : BaseEntity 
{
    [Key]
    public int ID { get; set; }
    public virtual ICollection<AddressBook> AddressBookEntries { get; set; }

    public IEnumerable<Address> Addresses
    {
        get { return AddressBookEntries.Select(ab => ab.Address); }
    }
}

(The same with Company .)

An alternative and in my opinion better approach would be to create a common base class for Person and Company , move the Addresses collection into that base class and have a single many-to-many relationship and single join table between this base class and Address :

public abstract class EntityWithAddresses : BaseEntity
{
    [Key]
    public int ID { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

public partial class Person : EntityWithAddresses 
{
}

public partial class Company : EntityWithAddresses 
{
}

Address has a navigation collection to the new base class:

public partial class Address : BaseEntity
{
    [Key]
    public int ID { get; set; }
    public string Street { get; set; }
    public string CityName { get; set; }
    public int? PostalCode { get; set; }

    public virtual ICollection<EntityWithAddresses> EntityWithAddresses { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM