Reputation: 2973
For example Project
has references (1 optional, 1 required) to the User
:
public class Project {
public User RequiredUser { get; set; }
public User OptionalUser { get; set; }
}
whereas User
has many projects:
public class User {
public ICollection<Project> Projects { get; set; }
}
Would it be right to configure it like that:
modelBuilder.Entity<User>()
.HasMany(i => i.Projects)
.WithRequired(i => i.RequiredUser);
modelBuilder.Entity<Project>().HasOptional(i => i.OptionalUser);
Upvotes: 2
Views: 109
Reputation: 23093
I think you code would work, but not they way you expect it to:
ICollection<Project> Projects
will only contain Project
instances where the User
is the RequiredUser
.
I personally would use an intermediate table which has a IsRequired
flag to map these two entities, but that changes the behaviour a little and introduces a not so easy to handle many-to-many
relationship:
public class Project {
public ICollection<ProjectUser> Users { get; set; }
}
public class ProjectUser {
public Project Project { get; set; }
public User User { get; set; }
public bool IsRequired { get; set; }
}
public class User {
public ICollection<ProjectUser> Projects { get; set; }
}
The advantage is, that you can have more "optional users" (or required) in one project, but if your requirement is to only have on (required) user you would need to take care of this contraint in your business logic. You could also replace the bool
with an enum if you have more then two possible "mapping types", e.g. Owner
, Developer
and Tester
.
NOTE: If you have no use for this advantage you are better of with Flater's answer.
Upvotes: 1
Reputation: 13763
From experience, if you set up separate relations (RequiredUser
/ OptionalUser
), you'l also need separate IEnumerable<Project>
properties in your User
class.
public class User {
public ICollection<Project> Projects_Required { get; set; }
public ICollection<Project> Projects_Optional { get; set; }
}
Your setup then becomes:
modelBuilder.Entity<User>()
.HasMany(i => i.Projects_Required)
.WithRequired(i => i.RequiredUser);
modelBuilder.Entity<User>()
.HasMany(i => i.Projects_Optional)
.WithOptional(i => i.OptionalUser);
You could then add a AllProjects
custom property that combines the two lists, if you so choose. However, it seems a dangerous thing to do, as you need to keep these lists separated because they address separate relations. To avoid confusion, I'd keep them separated as much as possible.
If there is a way to set up EF to have both relations end up in the same List property, I haven't found it. It seems hard and dangerous to implement.
Upvotes: 2
Reputation: 15571
This seems to be a case of circular reference (http://en.wikipedia.org/wiki/Circular_reference) and definitely become a bad design. Think of the design why you need to refer to a User
in Project
which is already inside a User
. Look more here: http://blogs.msdn.com/b/nickmalik/archive/2005/03/18/398601.aspx
Upvotes: 0