简体   繁体   中英

Entity Framework: Junction/Bridge And Child in One Table

I have a system which has Members, and a child table of MemberDependents. A Dependent must always have a parent Member, but a dependent can also be a member themselves.

I model this in the database like so:

CREATE TABLE dbo.MemberDependents(
    ID INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
    MemberID INT NOT NULL REFERENCES dbo.Members (ID) 
        ON UPDATE CASCADE ON DELETE NO ACTION
    MemberObjectID INT -- if not null, this links to what Member they are
);

My POCO like so:

public class Dependent
{
    public int ID { get; set; }
    public int MemberID {get;set;}          // FK
    public int? MemberObjectID {get;set;}   // optional

    public virtual Member Member {get;set;}         // FK
    public virtual Member MemberObject {get;set;}   // optional
}

Using EF's FluentAPI, I map the usual FK relationship:

modelBuilder<Dependent>()
    .HasRequired(x => x.Member)
    .WithMany(x => x.Dependents)
    .HasForeignKey(x => x.MemberID);

... but I'm not sure how to map that optional "this dependent is a member themselves, and that member is..."

modelBuilder<Dependent>()
    .HasOptional(x => x.MemberObject)
    .????
    .HasForeignKey(x => x.MemberObjectID);

How can I map MemberObject using EF FluentAPI?

Update: the (truncated) member model:

public class Member
{
    public int ID {get;set;}

    // name, address, etc

    // a few other unrelated properties and methods

    // this is the usual child table
    public virtual ICollection<Dependent> Dependents {Get;set;}

}

The Member model has nothing in it to represent this oddball relationship from the Dependent (doesn't seem semantic to put anything in there for it...)

As a side note, I can get away with tossing in a GetMemberObject() method in the Dependent and handle it manually, but I'm a bit curious to see how to handle this with EF.

You have two Member type FK properties in Dependent class - Member and MemberObject , but only one "inverse" ICollection<Dependent> type property in Member class.

Since you already mapped Dependent.Member to Member.Dependents , you need to either add another collection like

public virtual ICollection<Dependent> DependentOf { get; set;}

and map the MemberObject to it:

modelBuilder<Dependent>()
    .HasOptional(x => x.MemberObject)
    .WithMany(x => DependentOf)
    .HasForeignKey(x => x.MemberObjectID);

or if you want to keep the relationship unidirectional (w/o corresponding collection), EF provides parameterless overload for WithXYZ methods specifically for such scenarios (in contrast HasXYZ always require argument, so it's important to start the mapping with the entity having the navigation property):

modelBuilder<Dependent>()
    .HasOptional(x => x.MemberObject)
    .WithMany()
    .HasForeignKey(x => x.MemberObjectID);

Please note that the WithXYZ overload used should match the presence of a navigation property, otherwise you will get unexpected surprises.

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