好的..我正在建立一个博客评论和回复部分,我将这三个类映射到我的数据库..第一个类包含一篇文章的相关评论的集合..第二个类包含相关评论的集合到评论..
public class Article
{
public int ArticleID { get; set; }
public byte[] Image { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime DatePublished { get; set; }
public string Author { get; set; }
public CategoryTyp Category { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int CommentID { get; set; }
public int ArticleID { get; set; }
public int CategoryID { get; set; }
public int UserID { get; set; }
public string Description { get; set; }
public DateTime CommentDate { get; set; }
public virtual ICollection<Remark> Remarks { get; set; }
}
public class Remark
{
public int RemarkID { get; set; }
public int CommentID { get; set; }
public int ArticleID { get; set; }
public string RemarkDetail { get; set; }
public DateTime RemarkTime { get; set; }
}
在我的控制器内...
public ActionResult GetArticle(int id)
{
var article = db.Articles.Include("Comments").Where(a => a.ArticleID == id).SingleOrDefault();
return View(article);
}
我理解急切加载的基础,但我的问题是:
1)当您从多个相关表中提取数据时,如何实现它?
2)将其填充到View中的最佳做法是什么?一旦我创建了一个View Model,我如何填充相关的集合?请举例..
由于
答案 0 :(得分:2)
1)使用多个相关表格,您可以有两种情况:
a)多个顶级关系:你只需添加多个Include语句(我建议使用lambda表达式代替字符串,以避免拼写错误)。
db.Articles
.Include(a=>a.Comments)
.Include(a=>a.SomethingElse)
.FirstOrDefault(a=>ArticleID==id); // Side note: I would suggest this instead of your Where plus SingleOrDefault
对于这些场景,我总是使用辅助方法,如this one。
b)多个嵌套相关实体:
db.Articles
.Include(a=>a.Comments.Select(c=>c.Remarks)
.FirstOrDefault(a=>ArticleID==id);
2)您对如何将数据传递给视图有点了解。我可以告诉你的一个最佳实践是,你不应该让视图延迟加载任何依赖实体或集合。因此,您使用Include是正确的,但我甚至建议删除虚拟(停用延迟加载)以避免意外错过包含。
关于您提到的ViewModel,您实际上并未使用视图模型,而是使用数据模型。在大多数情况下这是可以的,除非您需要以某种方式格式化数据或添加额外信息。然后,您需要创建一个视图模型,并从来自EF的数据中映射它。
另一种情况是使用WebAPI或Ajax Action。在这种情况下,我建议使用DTO(相当于ViewModel)来更好地控制返回的数据及其序列化。
关于ViewModels的最后一条评论是,如果您有大量实体但只需要一些属性,那么最好选择使用Projections来指示EF只加载所需的属性,而不是整个对象。
db.Articles .INCLUDE(A =&GT; a.Comments) .Select(a =&gt; new ArticleDto {Id = a.ArticleID,Title = a.Title}) .ToListAsync();
这将转换为&#34; SELECT ArticleID,Title FROM Articles&#34;,避免返回您可能不需要的文章正文和其他内容。
答案 1 :(得分:1)
您可以将关系与Include
联系起来。例如:
var article = db.Articles.Include("Comments.Remarks").Where(a => a.ArticleID == id).SingleOrDefault();
但是,我不确定你的第二个问题是什么意思。通过发出此查询,您已经拥有了这些注释的所有注释和所有注释。因此,您可以从开箱即用的文章实例中访问它们:
foreach (var comment in article.Comments)
{
...
foreach (var remark in comment.Remarks)
{
...
}
}
您如何使用视图模型处理完全取决于您。您可以将评论/评论映射到他们自己的模型,直接在视图模型上设置等等。这完全取决于您的应用程序的需求,除了您之外没有人可以说出来。