将具有多个引用的实体映射到同一类型

时间:2014-05-05 08:15:57

标签: c# .net entity-framework

例如ProjectUser的引用(1个可选,1个必需):

public class Project {
    public User RequiredUser { get; set; }
    public User OptionalUser { get; set; }
}

User有很多项目:

public class User {
    public ICollection<Project> Projects { get; set; }
}

这样配置是否正确:

modelBuilder.Entity<User>()
    .HasMany(i => i.Projects)
    .WithRequired(i => i.RequiredUser);

modelBuilder.Entity<Project>().HasOptional(i => i.OptionalUser);

3 个答案:

答案 0 :(得分:2)

根据经验,如果您设置了单独的关系(RequiredUser / OptionalUser),那么您的IEnumerable<Project>课程中还需要单独的User属性。

public class User {
    public ICollection<Project> Projects_Required { get; set; }
    public ICollection<Project> Projects_Optional { get; set; }
}

您的设置将变为:

modelBuilder.Entity<User>()
    .HasMany(i => i.Projects_Required)
    .WithRequired(i => i.RequiredUser);

 modelBuilder.Entity<User>()
    .HasMany(i => i.Projects_Optional)
    .WithOptional(i => i.OptionalUser);

可以然后添加AllProjects自定义属性,如果您愿意,可以将两个列表组合在一起。但是,这似乎是一件危险的事情,因为你需要将这些列表分开,因为它们解决了单独的关系。为了避免混淆,我会尽可能地将它们分开。

如果有办法设置EF以使两个关系在同一个List属性中结束,我还没有找到它。实施起来似乎很难而且很危险。

答案 1 :(得分:1)

我认为你的代码会起作用,但不是你想象的那样:
ICollection<Project> Projects只会包含ProjectUser的{​​{1}}个实例。

我个人会使用一个带有RequiredUser标志的中间表来映射这两个实体,但这会稍微改变一下行为并引入一个不太容易处理的IsRequired关系:

many-to-many

优点是,您可以拥有更多&#34;可选用户&#34; (或必需)在一个项目中,但如果您的要求仅限于(必需)用户,则需要在业务逻辑中处理此约束。如果您有两个以上的可能&#34;映射类型&#34;,您也可以用枚举替换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; } } boolOwnerDeveloper

注意:如果您没有使用此优势,那么您最好使用Flater的答案。

答案 2 :(得分:0)

这似乎是循环引用(http://en.wikipedia.org/wiki/Circular_reference)的情况,肯定会成为一个糟糕的设计。考虑一下设计,为什么需要引用UserProject已经在User内的{{1}}。在这里查看更多:http://blogs.msdn.com/b/nickmalik/archive/2005/03/18/398601.aspx

相关问题