Правильный способ передачи объектов Entity между слоями? - PullRequest
3 голосов
/ 05 ноября 2010

Я только изучаю Entity Framework и добился определенного прогресса в его интеграции с моей многоуровневой структурой кода. У меня есть 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 Ответ

5 голосов
/ 05 ноября 2010

Поскольку вы возвращаете IQueryable из своего DAL, вы не можете использовать , используя оператор .

Запрос отложен до тех пор, пока не будет запущен запрос - .ToList в вашем BLL.

К этому времени контекст будет удален.

Подумайте тщательно об использовании 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();
 }
}
...