1

This question is not about how to test the data access, nor the repository. It's about the problem i have when i want to use my POCO classes (that i've made with TDD) in the project. I mean, this is the problem because of the Linq to Entities limitations (or may be my problem about the design of the classes).

The classes i've arrived to through TDD are the next (extremely simplificated, of course):

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

Pretty simple, right?

So... what's the problem then? Let's see... When i want to retrieve from the database all the data from the courses (the course class has a lot of subcollections in the reality model) applying filters to them, the only way i could do it was like this:

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

As you know, it returns an error because of the GetGreatStudents() function:

LINQ to Entities does not recognize the method [...] this method cannot be translated into a store expression.

I mean, i know i could replace the method directly with the .Where(n => n.Average > 8) but it is awful (and in the reality there are a lot of filters), and on that way, what's the point with TDD if i can't use the api i've built and tested?

So, my question is for those who have experience developing with TDD and Entity Framework, how can you achieve the use of the beautiful API you design through TDD when you work with Linq to Entities?

ascherman
  • 1,762
  • 2
  • 20
  • 41
  • Have you read this: http://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet – Colin Dec 20 '13 at 15:01
  • I don't follow you @Colin, how is this helping me? – ascherman Dec 20 '13 at 15:23
  • FYI: In the real classes i don't have the IEnumerable<> but the Collection<> – ascherman Dec 20 '13 at 15:25
  • This and the links from it might be more useful http://stackoverflow.com/q/18109547/150342 – Colin Dec 21 '13 at 09:01
  • I'm confused. What this has to with TDD? Your question does not state of attempting write a Unit Test? Even after making asumptions that you trying to TDD the code above, I cannot see what's the actual problem you having as the obj.GetGreatStudents() should hide implementation detail and should return what it suppose to. Or am I missing something here? – Spock Dec 21 '13 at 23:03
  • No @Spock , i named TDD because i develope the class' interface through this. So my question is how to use this with linq to entities – ascherman Dec 22 '13 at 23:27
  • And @Spock, the problem is that i can't execute obj.GetGreatStudents() because this methods is not mappable to Linq to SQL (it throws an exception). So my question is related with how to use this object methods for mantaining the domain design but permorming everything in the same query. – ascherman Dec 27 '13 at 11:09

1 Answers1

1

Firstly, I agree that this is a TDD problem (since you run into it when using TDD!)

The problem you are having is that you have not been able to achieve persistence ignorance; your entities are tied to SQL (and therefore I would argue that they are not POCOs strictly speaking because they are tied to a particular framework)

The only solution I found to this problem was to separate the domain model objects from the persistence model objects (i.e. the EF objects) and write a library that was able to map from my domain objects to my persistence objects. This is a lot of work and I would question whether it was worth it for small projects. If you put pragmatism before purism it is far easier (but less satisfying) to simply understand that you cannot do such things in the EF even though you can write unit tests for them.

I found this and this to be helpful, although a little one-sided.

Your question is an old post so if you've found a better way I'd love to hear it.

mark_h
  • 5,233
  • 4
  • 36
  • 52