Reputation: 2273
Consider this scenario:
public class House
{
public string Name { get; set; }
public virtual Person Person1 { get; set; }
public virtual Person Person2 { get; set; }
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public House House { get; set; }
}
// Relationships
this.HasOptional(t => t.Person1)
.WithRequired(t => t.House);
this.HasOptional(t => t.Person2)
.WithRequired(t => t.House);
When I try to insert an instance of House a MetaDataException is thrown:
Schema specified is not valid. Errors: (36,6) : error 0040: Type House_Person1 is not defined in namespace Company.Models (Alias=Self).
After a little more hacking, figured that this works:
// Relationships
this.HasOptional(t => t.Person1)
.WithRequired();
this.HasOptional(t => t.Person2)
.WithRequired();
But then I won't have the Person.House property populated by EF. Can I emulate this behavior (shown below)?
public virtual Person Person1
{
get
{
return _person1;
}
set
{
_person1 = value;
_person1.Haushalt = this;
}
}
public virtual Person Person2
{
get
{
return _person2;
}
set
{
_person2 = value;
_person2.Haushalt = this;
}
}
Upvotes: 1
Views: 161
Reputation: 177163
You cannot use the same navigation property (Person.House
) in two different relationships (House_Person1
and House_Person2
).
An additional limitation is that EF only supports shared primary key associations as true one-to-one relationships. It means that a related House
and Person
must have the same primary key value. But from that follows that House.Person1
and House.Person2
would need to have the same PK value as the House
. In other words: Person1
and Person2
can never be different persons.
I would suggest that you map your relationship as a one-to-many relationship and ensure in your application's business logic that a House
must not have more than two Person
s. (Because your current mapping allows that Person1
and Person2
are optional, zero or only one person would be allowed):
public class House
{
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public House House { get; set; }
}
this.HasMany(t => t.People)
.WithRequired(t => t.House);
Edit
If you want to keep the two Person
navigation properties in House
you can only map this as two one-to-many relationships (even if this relation in wrong from business viewpoint) without having a navigation property in Person
(like shown here):
this.HasOptional(t => t.Person1)
.WithMany();
this.HasOptional(t => t.Person2)
.WithMany();
You can use the House
property in Person
as you did in your last code snippet, but you need to exclude it from the model:
modelBuilder.Entity<Person>()
.Ignore(t => t.House);
Person.House
isn't a navigation property anymore you can't load it (with eager or lazy loading) when you load a Person
entity from the database.
Upvotes: 2