Reputation: 7792
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.
Upvotes: 0
Views: 30
Reputation: 205589
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.
Upvotes: 1