TDD и CodeFirst (Entity Framework)
Этот вопрос не о том, как проверить доступ к данным, ни о хранилище. Речь идет о проблеме, которая возникает у меня, когда я хочу использовать свои классы POCO (которые я создал с помощью TDD) в проекте. Я имею в виду, что это проблема из-за ограничений Linq to Entities (или, может быть, моя проблема с дизайном классов).
Классы, к которым я прибыл через TDD, следующие (конечно, очень упрощенные):
public class Person{
public int IdPerson{ get; set; }
public string Name { get; set; }
public int Average { get; set; }
}
public class Course{
public int IdCourse { get; set;}
public Person Professor { get; set;}
public IEnumerable<Person> Staff { get; set;}
public IEnumerable<Person> Students { get; set;}
public IEnumerable<Person> GetGreatStudents(){
return Students.Where(n => n.Average > 8);
}
}
Довольно просто, правда?
Итак... в чем проблема тогда? Давайте посмотрим... Когда я хочу извлечь из базы данных все данные из курсов (у класса курса много подколлекций в модели реальности), применяя к ним фильтры, единственный способ, которым я мог это сделать, был следующим:
var course = from obj in Courses //Doesn't matter how i get the courses' collection
select {
IdCourse = obj.IdCourse,
GreatStudents = obj.GetGreatStudents(), // Here is the problem
OtherCollection = obj.OtherCollection.Where(n => n.Active).Select(n => n.Property1)
}
Как вы знаете, он возвращает ошибку из-за функции GetGreatStudents():
LINQ to Entities не распознает метод [...], который нельзя преобразовать в выражение хранилища.
Я имею в виду, я знаю, что мог бы заменить метод напрямую на .Where(n => n.Average > 8), но это ужасно (а в реальности много фильтров), и в этом смысле, какой смысл с TDD, если я не могу использовать API, который я создал и протестировал?
Итак, мой вопрос для тех, кто имеет опыт разработки с TDD и Entity Framework, как вы можете добиться использования прекрасного API, который вы разрабатываете с помощью TDD, когда вы работаете с Linq to Entities?
1 ответ
Во-первых, я согласен, что это проблема TDD (поскольку вы сталкиваетесь с ней при использовании TDD!)
Проблема, с которой вы сталкиваетесь, заключается в том, что вы не смогли достичь постоянного невежества; ваши объекты связаны с SQL (и поэтому я бы сказал, что они не являются POCO, строго говоря, потому что они связаны с конкретной структурой)
Единственное решение, которое я нашел для этой проблемы, состояло в том, чтобы отделить объекты модели домена от объектов модели персистентности (то есть объектов EF) и написать библиотеку, которая могла бы сопоставлять объекты моего домена с моими объектами персистентности. Это много работы, и я бы усомнился, стоило ли это того, что нужно для небольших проектов. Если вы ставите прагматизм перед пуризмом, гораздо проще (но не так приятно) просто понять, что вы не можете делать такие вещи в EF, даже если вы можете написать для них модульные тесты.
Я нашел это и это полезным, хотя и немного односторонним.
Ваш вопрос - старый пост, поэтому, если вы нашли лучший способ, я бы с удовольствием его услышал.