我可以使用没有上下文的实体吗? - c#

假设我有一个User实体,并创建了部分User类,因此我可以添加一些方法(例如NHibernate)。我添加了GetByID以使用户更容易:

public static User GetByID(int userID)
{
    using (var context = new MyEntities())
    {
        return context.Users.Where(qq => qq.UserID == userID).Single();
    }
}

现在,在业务逻辑中的某处我想做这样的事情:

var user = User.GetByID(userID);
var posts = user.GetAllPostsForThisMonth();
foreach(var post in posts)
{
    Console.WriteLine(post.Answers.Count);
}

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();
    }
}

这将产生一个SQL查询,并且在一次往返过程中将准确产生您想要的信息,而不会加载大量您不想要的信息。
更新资料
如果NHibernate可以像Java的Hibernate一样工作,那么在处理完上下文后,它也不会进行延迟加载。实体框架确实为您提供了许多选择,具体取决于您的具体情况。例如:

可以使上下文的持续时间更长(例如,在Web应用程序中每个请求一次),而不是将上下文范围限制在数据访问方法之内,以便使属性的延迟加载将继续在数据访问方法之外进行。
您可以热切地加载所需的任何实体关联。

这是一个渴望加载的例子:

public GetAllPostsAndAnswersForThisMonth()
{
    using (var context = new MyEntities())
    {
        return context.Posts.Include("Answers")
                   .Where(p => p.UserID == UserID)
                   .ToList();
    }
}

但是,由于Entity Framework本质上构成了您的“数据访问”层,因此我仍然认为,最佳实践是创建一个或一组类来准确地建模您的业务层实际想要从数据层中获取的内容,然后数据访问方法产生这些类型的对象。

使用Entity Framework Core(2.1)调用标量函数的最佳实践 - c#

我经常需要从Web应用程序(ASP.NET Core / EF Core)中调用在SQL Server上定义的标量函数。由于这些函数只是简单的辅助函数,因此我也使用了许多辅助函数,因此我使用了通用模式来调用这些标量函数-借助EF Core 2.1可用的新查询类型。由于我是EF Core的新手,所以我的问题是这种模式是否会引起问题,并且/或者是否存在调用标量函…

Play Framework 2中的系统类加载器 - java

我使用的是Play 2.2.2,我有一个外部jar,它试图从同一jar的根目录加载XML资源。它使用System.class.getClassLoader().getResource("/Blabla.xml")这样做。这失败了,因为显然Play拥有一个奇怪的类加载器层次结构:ReloadableClassLoader和几个父级。该层次结…

如何以编程方式将ListView滚动到最后一个元素-Compact Framework - c#

我正在使用Windows Mobile 6.1上的3.5 Compact Framework开发应用程序。我有一个ListView,添加项目时想自动滚动此列表。我能怎么做? 参考方案 listView.EnsureVisible(listView.Items.Count - 1);

如何在命令行上更改连接字符串以在迁移到Entity Framework Core中的新数据库时更新数据库 - c#

首先在ASP.NET Core和EF Core代码中,我有一个多租户的webapp。创建新租户时,我想更改连接字符串,在其上添加迁移,然后更新。从命令行,添加迁移无法在租户上获得动态的连接字符串,因此在应用程序首次以新租户开始时,我没有有效的连接字符串来创建新数据库。有什么解决办法吗?谢谢 参考方案 您在找这个吗?编辑:这是为EF 6.1Update-Dat…

模块化C#Compact Framework 2.0应用程序 - c#

我们目前正在开发新的手持软件。我无法讨论应用程序的性质,因此我将使用一个示例。我们正在设计用于管理学校的手持软件。我们希望对系统的各个方面进行模块化,以便不同的学校可以使用不同的功能。我们的系统将从主菜单和登录屏幕开始。我希望这可以作为系统的基础,并成为要添加模块的位置。即我将有一个名为SchoolPda的项目。然后,我想拥有不同的模块。即,我想要一个注册模…