Reputation: 165
I have two tables
People Relation
------------- -----------------
Id (int) Id (int)
Name (string) ParentPeopleId (int)
ChildPeopleId (int)
I need to get all people by Relation table with union all. The relation table has two foreign keys. And there is one problem with mapping them. The mapping is one to many. People has many Relation, Relation has one People.
I mapped them like this:
HasRequired(r=> r.People).WithMany(p=>p.Relation).HasForeignKey(r=>r.ChildPeopleId);
So, how can I map the second foreign key?
Upvotes: 1
Views: 2085
Reputation: 39326
Per each FK column in your Relations
table you should have a navigation property in your Relation
entity (this is not mandatory, but what is mandatory is have at least one navigation property between the entities involve in the relationship). In this case you have two relationships between People
and Relations
, and a navigation property represents one end in an relationship. Your model could be this way:
public class Relation
{
public int Id {get;set;}
public int ParentPeopleId {get;set;}
public int ChildPeopleId {get;set;}
public virtual People ParentPeople {get;set;}
public virtual People ChildPeople {get;set;}
}
public class People
{
public int Id {get;set;}
public string Name {get;set;}
public virtual ICollection<Relation> ParentRelations {get;set;}
public virtual ICollection<Relation> ChildRelations {get;set;}
}
And the Fluent Api configurations like this:
HasRequired(r=> r.ParentPeople ).WithMany(p=>p.ParentRelations ).HasForeignKey(r=>r.ParentPeopleId);
HasRequired(r=> r.ChildPeople).WithMany(p=>p.ChildRelations ).HasForeignKey(r=>r.ChildPeopleId );
Now if you don't want to work with one of the collection navigation properties in your People
entity, you can create an unidirectional relationship. For example if you don't want ParenRelations
navigation property, you can configure that relationship as follow:
HasRequired(r=> r.ParentPeople).WithMany().HasForeignKey(r=>r.ParentPeopleId);
Let me start first with a suggestion. I thing your table Relation
is not playing any role is you have only those columns. If a person con only have a parent I would change your model to the following:
public class People
{
public int Id {get;set;}
public string Name {get;set;}
public int ParentId {get;set;}
public virtual People Parent {get;set;}
public virtual ICollection<People> Children {get;set;}
}
And you relationship configuration would be:
HasOptional(r=> r.Parent).WithMany(p=>p.Children).HasForeignKey(r=>r.ParentId);
Now going back to your current model, EF sees your ChildPeopleId
property as an simple scalar column, it doesn't know it's a FK column, that's way I suggested above map two relationship instead one.
Another thing, with the below line
var Peoplelist = MyDbContext.People.Include(p=>p.Relations.Select(r=>r.People)).ToList();
You are telling to EF that you want to load the Relation
entities related to a People
, but also you want to load the People
related with each Relation
, which is at the same time the same People
where the Relation
came from, so, you don't need to do the last select, if your data is properly related, that People
navigation property is going to be loaded when you execute your query,so, that query should be this way:
var Peoplelist = MyDbContext.People.Include(p=>p.Relations).ToList();
Upvotes: 1