views:

164

answers:

4

In my service layer for my MVC application I am attempting to convert the linq to sql entity results into my business model entities. I am currently attempting the following code:

    public IList<Project> GetAllProjects()
    {
        var results = from p in _context.Repository<DBMappings.project>()
                      select p;

        foreach (DBMappings.project prj in results.ToList<DBMappings.project>())
            yield return CreateProjectEntityFromDBProject(prj);

    }

Unfortunately, this doesn't seem to work and the only thing I can guess is that yield only works with IEnumerable. Is there any other solution besides creating a new list, adding items in the foreach loop and returning the list? I need to use an IList because methods that use the returned list need to be able to do List Methods such as .Sort().

+1  A: 

IList<T> describes functionality that is incompatible with IEnumerable<T>, at least as far as lazy loading goes.

Being able to go to a specific index a la IList<T>, requires that the whole enumeration be 'enumerated', at least up to the specified index.

If you don't care about the evaluation of the entire IEnumerable<T>, then you can construct a List<T> taking the IEnumerable<T> as a constructor parameter, and then return the List<T> as an IList<T>

John Weldon
+6  A: 

if you want to .Sort() you should definitely create a list in your method. using yield saves you some memory - because results are not stored as a single object. This is useful when you just want to walk over results. but if you want to Sort something you need it in memory as a single piece.

Andrey
+1 for comments on Sorting..
John Weldon
That makes sense, thanks :)
KallDrexx
let me give you common advise on yield. Use it when you definitely know that it is useful for current task. If you doubt don't use it. :)
Andrey
+2  A: 

Section 8.14 of the C# specification (emphasis mine):

The yield statement is used in an iterator block (§8.2) to yield a value to the enumerator object (§10.14.4) or enumerable object (§10.14.5) of an iterator or to signal the end of the iteration.

IList implements IEnumerable, but it does not implement IEnumerator.

fatcat1111
Ah that explains part of my confusion. I didn't realize there was an IEnumerator, I thought it was just IEnumable
KallDrexx
+2  A: 

You can't "lazy return" a list, but it seems like you could get what you want with:

return results.Select(prj=>CreateProjectEntityFromDBProject(prj)).ToList();

or just

var results = from p in _context.Repository<DBMappings.project>()
                  select CreateProjectEntityFromDBProject(p);
return results.ToList();
JasonTrue
Ah good idea! Didn't realize I could do either of those.
KallDrexx
Thanks to how different Linq looks from normal C#, it's easy to forget that it's still C# in there...
JasonTrue