在层之间传递Entity对象的正确方法?

时间:2010-11-04 21:18:34

标签: entity-framework-4 idisposable objectcontext

我正在学习实体框架,并且在将其与我的分层代码结构相结合方面取得了一些进展。我有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方法中删除使用,它可以正常工作。

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

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

1 个答案:

答案 0 :(得分:5)

由于您从DAL返回 IQueryable ,因此无法使用使用语句。

查询 deferred ,直到在您的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();
 }
}