Entity framework EF6加载上下文跟踪的实体的未映射字段的最佳实践
考虑到博客数据模型:Entity framework EF6加载上下文跟踪的实体的未映射字段的最佳实践,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,考虑到博客数据模型: Blog: int Id ICollection<Post> Posts Post: int Id int BlogId DateTime Date 博客: 整数Id I收集站 职位: 整数Id intblogid 日期时间日期 然后加载带有最新文章日期(LatestPostDate)的博客并绑定到UI,同时由上下文跟踪它们 有一些解决方案,例如使用DTO,但是结果实体不会被上下文跟踪。 我还可以将LatestPostDate设置为NotMapped,定义
Blog:
int Id
ICollection<Post> Posts
Post:
int Id
int BlogId
DateTime Date
博客:
整数Id
I收集站
职位:
整数Id
intblogid
日期时间日期
然后加载带有最新文章日期(LatestPostDate)的博客并绑定到UI,同时由上下文跟踪它们
有一些解决方案,例如使用DTO,但是结果实体不会被上下文跟踪。
我还可以将LatestPostDate设置为NotMapped,定义一个表值函数,并在DbSet上应用SqlQuery。尽管如此,NotMapped字段并不是以这种方式加载的
最佳实践是什么
我尽量不向表中添加列,也避免在加载后计算值。最佳做法是处理ViewModel中的显示问题 但是,由于您不想将实体映射到另一个类,我们首先来看一下
[NotMapped]
变量,它使用LINQ来计算最新的发布日期,而不是简单的SQL
using System.Linq;
public class Blog {
public int Id { get; set; }
public virtual ICollection<Post> Posts { get; set; }
[NotMapped]
public DateTime? LatestPostDate {
get {
return Posts.OrderBy(p => p.Date).LastOrDefault()?.Date;
}
}
}
但如果使用ViewModel,则可以一次性填写LatestPostDate
:
public class BlogViewModel {
public int Id { get; set; }
public DateTime? LatestPostDate { get; set; }
}
var viewModels = _dbContext.Blogs.Select(b => new BlogViewModel {
Id = b.Id,
LatestPostDate = b.Posts.OrderBy(p => p.Date).LastOrDefault()?.Date;
}).ToArray();
关于您对ViewModel不被上下文跟踪的担忧:在编辑用例中,使用ViewModel提供的Id再次加载实体,并映射更新的属性。这使您可以完全控制应可编辑的属性。另外,ViewModel是进行输入验证、格式化等的好地方。DTO(ViewModels)是一种最佳实践(分离关注点)。使用它们来创建视图,并在需要时将其移动到实体中。“Automapper是这方面的一个很好的帮手。”我想是的。特别是因为关注点的分离是不可避免的。我想避免这两种解决方案。第一个会导致多个DB周转,可以一次完成。第二,需要我通过EF API和自跟踪实体等解决方案处理变更跟踪。但我想没有出路了。
public class BlogViewModel {
public int Id { get; set; }
public DateTime? LatestPostDate { get; set; }
}
var viewModels = _dbContext.Blogs.Select(b => new BlogViewModel {
Id = b.Id,
LatestPostDate = b.Posts.OrderBy(p => p.Date).LastOrDefault()?.Date;
}).ToArray();