【问题标题】:Correct way to pass Entity objects between layers?在层之间传递实体对象的正确方法?
【发布时间】:2010-11-05 09:16:40
【问题描述】:

我刚刚学习了实体框架,并且在将它与我的分层代码结构相结合方面取得了一些进展。我有 2 个可视层,一个业务层和一个数据访问层。

我的问题是在层之间传递实体对象。此代码示例不起作用:

// BLL
public static void Test1()
{
 List<User> users = (from u in GetActiveUsers()
      where u.ID == 1
      select u).ToList<User>();

 // Do something with users
}

// DAL
public static IQueryable<User> GetActiveUsers()
{
 using (var context = new CSEntities())
 {
  return from u in context.Users
      where u.Employee.FirstName == "Tom"
      select u;
 }
}

我收到错误消息ObjectContext 实例已被释放,不能再用于需要连接的操作。

如果我从 GetActiveUsers 方法中删除 using,它可以正常工作。

我知道这是危险的做法,因为 GC 可以在任何给定时间处理上下文并搞砸我的 BLL。

那么,在层之间传递信息的正确方法是什么?我是否也需要传递上下文?

【问题讨论】:

    标签: entity-framework-4 idisposable objectcontext


    【解决方案1】:

    因为您要从 DAL 返回 IQueryable,所以不能使用 using 语句。

    查询被延迟,直到触发查询 - 您的 BLL 中的 .ToList

    到那时,上下文就被释放了。

    仔细考虑使用 IQueryable,因为在不了解所有细节的情况下这是一种冒险的做法。

    既然你还在学习 EF,我会保持简单:

    // BLL
    public static void Test1()
    {
     List<User> users = GetActiveUsers();
     var singleUser = users.SingleOrDefault(u => u.ID == 1);
    
     // Do something with users
    }
    
    // DAL
    public static ICollection<User> GetActiveUsers()
    {
     using (var context = new CSEntities())
     {
      var users = from u in context.Users
          where u.Employee.FirstName == "Tom"
          select u;
      return users.ToList();
     }
    }
    

    如果要获取单个用户,请创建另一个方法:

    // DAL
    public static User GetSingleActiveUser(int userId)
    {
     using (var context = new CSEntities())
     {
      var users = from u in context.Users
          where u.Employee.UserId == userId
          select u;
      return users.SingleOrDefault();
     }
    }
    

    【讨论】:

    • 感谢您的建议。但是,如果我将我的实体转换为 DAL 中的列表,我不会失去我使用 EF 获得的所有功能吗?比如,如果我希望能够在 Silverlight 中进行分页,我不一定要将整个数据集加载到列表中,对吧?
    • 有点。使用 IQueryable,您可以稍后“建立”查询(即延迟执行)。这给了你很大的力量。我也使用 IQueryable 的。但正如我所说,使用 IQueryable 时不能使用“使用”语句。您需要从其他地方手动打开/关闭上下文,我强烈建议为此使用 IoC 容器(如 StructureMap)。否则,您最终会遇到旧连接。
    • 不——你并没有真正失去功能,你只是失去了对 DAL 之外的查询进行粗粒度控制的能力。您仍然可以进行分页,只需创建一个接受页码和页面大小的方法,然后在实际的 DAL 方法中进行分页并返回列表。如果您对 IQueryable 感兴趣,请查看我提出的一些问题,因为正如我所说,我目前正在使用它。此外,让 Silverlight 应用程序执行查询为时已晚。您应该只将查询推迟到 BLL,不能稍后。否则你可能会得到意想不到的结果。
    猜你喜欢
    • 2011-06-17
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    相关资源
    最近更新 更多