热门示例:在问题跟踪器JIRA中,问题可以与其他问题相关联。链接本身附有一些数据,特别是一种类型。
示例:
问题A - > 取决于 - > 问题B
问题B < - 取决于< - 问题A
我们正在使用EF 4.1 CodeFirst为我们的C#ASP.NET MVC应用程序中的实体引入相同类型的关系,我想知道如何最好地建模这种关系?
详情:
这种情况有一些特殊之处:
我们肯定会有一个链接实体,如下所示:
public class Link
{
public int ID { get; set; }
public Issue IssueA { get; set; }
public Issue IssueB { get; set; }
public LinkType Type { get; set; }
}
问题类可能如下所示:
public class Issue
{
public int ID { get; set; }
public virtual ICollection<Link> Links { get; set; }
}
目前只有一种链接类型:依赖。因此,链接类型如下所示:
public class LinkType
{
public int ID { get; set; }
public string ForwardName { get; set; } // depends on
public string BackwardName { get; set; } // is depended on by
}
现在提出一个大问题:
如果我希望EF自动管理Issue.Links
,我必须告诉它使用Link
表上的外键。要么我使用IssueA
,要么使用IssueB
。我不能同时使用,可以吗?
我要么定义:
modelBuilder.Entity<Issue>().HasMany(i => i.Links).WithRequired(l => l.IssueA);
或我定义:
modelBuilder.Entity<Issue>().HasMany(i => i.Links).WithRequired(l => l.IssueB);
可能的方法 - 我很好奇您对其中一些是否会导致问题,无法实施或是否可以将这些方法视为“最佳做法”的反馈:
ICollection<Link> OutgoingLinks
,ICollection<Link> IncomingLinks
。这样,集合可以由EF维护,但从业务逻辑的角度来看,它们没有多大意义。只添加一个集合并自行实现:
ICollection<Link> AllLinks { return _context.Links.Where(l => l.IssueA == this || l.IssueB == this).ToList(); }
这种方法的问题在于,域实体执行的数据访问任务在关注点分离方面是不好的。
还有其他吗?
答案 0 :(得分:2)
选项(1)是我认为的方式,以及一个结合两个集合的只读助手:
public class Issue
{
public int ID { get; set; }
public virtual ICollection<Link> OutgoingLinks { get; set; }
public virtual ICollection<Link> InComingLinks { get; set; }
public IEnumerable<Link> Links // not mapped because readonly
{
get { return OutgoingLinks.Concat(InComingLinks); }
}
}
选项(2)是不可能的,因为您无法将一个导航属性映射到两个不同的端/导航属性。