我对使用EF的循环依赖感到有些困惑,因为它似乎只会变成循环依赖。
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
当我在Vs2012中运行“代码映射”时,我确实看到它是循环引用
我不应该担心这个吗?我试图使用Autofixture生成虚拟数据但由于循环引用而崩溃。
答案 0 :(得分:2)
我想这取决于你问的是否应该担心或不关注双向关联。在域驱动设计中,人们通常会说你应该担心这一点。 例如。埃里克埃文斯在他的书Domain driven design: tackling the complexity in the heart of software中说,如果可能,你应该避免使用它们。
Julie Lerman在最近的帖子here
中写到了这个问题在简单示例中,如果您在Post上删除了Blog和BlogId属性,那么您提供的实体框架不应该有任何抱怨,但可能还有其他更复杂的情况。
默认情况下,实体会将数据库中的帖子行中的外键添加到拥有的博客行,但域模型只能从博客导航到帖子。
以下代码段将首先从数据库加载第一个博客,然后延迟加载该博客的帖子。
using (var db = new BlogContext())
{
var blog = db.Blogs.FirstOrDefault();
//lazy loading the Posts of the blog that was fetched in previous line
foreach (var post in blog.Posts)
{
Trace.TraceInformation(string.Format("Title of post {0} is {1}", post.Id, post.Title));
}
}
}
如果您确实需要同时从Blog发布到帖子以及从帖子到博客,由于应用程序中的某些业务需求,您必须在查询和双向关联之间做出决定。 选择哪一个完全取决于您,实体框架支持两者。
双向关联是指两侧都有导航属性,使您可以双向导航。即如果Blog有Posts属性,并且每个Post都有一个指向Blog的Blog属性,那么我们就会有双向关联。
另一种选择是仅在一侧具有导航属性。例如。博客可能包含帖子列表,这样可以轻松地从博客导航到帖子,这可能是最需要的。 如果您在某个用例中有一个Post的引用并且需要找出它所属的Blog,那么您可以通过对您的repository / dbcontext进行查询来搜索其列表中包含帖子的Blog对象来找到该博客邮政。
如果需要相反方向的导航,DDD的倡导者通常会建议单向导航和查询。