Epi*_*dex 2 c# entity-framework
假设我有一个User实体,并创建了部分User类,所以我可以添加一些方法(比如NHibernate).我添加GetByID了让用户更容易:
public static User GetByID(int userID)
{
using (var context = new MyEntities())
{
return context.Users.Where(qq => qq.UserID == userID).Single();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在业务逻辑的某个地方,我想做这样的事情:
var user = User.GetByID(userID);
var posts = user.GetAllPostsForThisMonth();
foreach(var post in posts)
{
Console.WriteLine(post.Answers.Count);
}
Run Code Online (Sandbox Code Playgroud)
GetAllPostsForThisMonth()类似于GetByID- 具有上下文并在执行后立即处理它.
通常我不能这样做,因为我打电话时会处理上下文post.Answers.Count.我认为这会使我的方法变得无用......或者我错过了什么?我能不能这样使用我的实体?或者我应该为我使用的每个查询创建方法(比如post.GetAnswersCount())?提前致谢!
你感叹的行为实际上很好,因为它可以防止你在脚下射击.如果你被允许这样做,它将导致n往返数据库(n帖子的数量),并且每次往返都会拉出所有答案的所有数据,当你所有的想要的是Count.这可能会产生巨大的性能影响.
您要做的是构造一个对象,该对象表示您希望从数据库中获取所需的所有信息,然后构造一个LINQ查询,该查询将实际加载您希望使用的所有信息.
public class PostSummary
{
public Post Post {get;set;}
public int AnswerCount {get;set;}
}
public IEnumerable<PostSummary> GetPostSummariesByUserAndDateRange(
int userId, DateTime start, DateTime end)
{
using (var context = new MyEntities())
{
return context.Posts
.Where(p => p.UserId == userId)
.Where(p => p.TimeStamp < start && p.TimeStamp > end)
.Select(new PostSummary{Post = p, AnswerCount = p.Answers.Count()})
.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
这会生成一个SQL查询,并且在一次往返中,可以生成您想要的信息,而无需加载大量您不想要的信息.
如果NHibernate的工作方式与Java的Hibernate类似,那么在上下文处理后它也不会进行延迟加载.实体框架确实为您提供了许多选项:哪一个最适合您将取决于您的具体情况.例如:
这是一个急切加载的例子:
public GetAllPostsAndAnswersForThisMonth()
{
using (var context = new MyEntities())
{
return context.Posts.Include("Answers")
.Where(p => p.UserID == UserID)
.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,由于实体框架基本上构成了您的"数据访问"层,我仍然认为最佳实践是创建一个类或一组类,这些类可以准确地模拟业务层实际需要的数据层,然后具有数据访问方法生成这些类型的对象.
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |