views:

146

answers:

3

Assuming these objects...

class MyClass
{
     int ID {get;set;}
     string Name {get;set;}
     List<MyOtherClass> Things {get;set;}
}

class MyOtherClass
{
     int ID {get;set;}
     string Value {get;set;}
}

How do I perform a LINQ to Entities Query, using a projection like below, that will give me a List? This works fine with an IEnumerable (assuming MyClass.Things is an IEnumerable, but I need to use List)

MyClass myClass = (from MyClassTable mct in this.Context.MyClassTableSet
                        select new MyClass
                        {
                             ID = mct.ID,
                             Name = mct.Name,
                             Things = (from MyOtherClass moc in mct.Stuff
                                       where moc.IsActive
                                       select new MyOtherClass
                                       {
                                            ID = moc.ID,
                                            Value = moc.Value
                                       }).AsEnumerable()
                        }).FirstOrDefault();

Thanks in advance for the help!

A: 

I'm not sure what exactly your asking about, but List<T> does implement IEnumerable<T> (which is just an interface for an enumerable sequence).

A code that will do your projection and have Things be a List instead of an IEnumerable would use the ToList() operator, which creates a List<T> from any IEnumerable<T> this:

MyClass myClass = (from MyClassTable mct in this.Context.MyClassTableSet
                        select new MyClass
                        {
                             ID = mct.ID,
                             Name = mct.Name,
                             Things = (from MyOtherClass moc in mct.Stuff
                                       where moc.IsActive
                                       select new MyOtherClass
                                       {
                                            ID = moc.ID,
                                            Value = moc.Value
                                       }).ToList()
                        }).FirstOrDefault();
Johannes Rudolph
ToList() on a LINQ to Entities Query is not supported, which is why I have asked this question.
Matthew
Is there some reference for this? MSDN's own LINQ to Entities shows you can in fact use ToList. http://msdn.microsoft.com/en-us/library/bb896246.aspx?ppud=4
sixlettervariables
You can use ToList() on the result of a query, but now within a query. In the example of your link, the ToList() is added to the end of a LINQ expression. In my code, it is embedded within the expression, hence, not supported.
Matthew
Gotcha, the root cause is LINQ to Entities cannot instantiate the `List<T>`, or any IEnumerable for that matter, inside of a query. http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx
sixlettervariables
+2  A: 

You don't. You have to do this part in L2O.

So you could do:

var q = (from MyClassTable mct in this.Context.MyClassTableSet
         select new // note anonymous type; important!
         {
             ID = mct.ID,
             Name = mct.Name,
             Things = (from MyOtherClass moc in mct.Stuff
                       where moc.IsActive
                       select new MyOtherClass
                       {
                           ID = moc.ID,
                           Value = moc.Value
                       }
          }).AsEnumerable();

MyClass myClass = (from mct in q
                   select new MyClass
                   {                 
                       ID = mct.ID,
                       Name = mct.Name,
                       Things = mct.Things.ToList()
                   }).FirstOrDefault();

There's no way to do this in one query.

Craig Stuntz
Thanks, I just figured this out too.
Matthew
A: 

This answer was helpful, but this is how I do this. This converts to POCOs, and can supported unlimited nested lists. Very simple but powerful:

        Product product = new Product();
        List<CoverageCondition> covCondList = null;
        CoverageCondition covCond = null;
        Question question = null;
        List<Question> questList = null;

        var prod = db.PRODUCTs.Include("COVERAGE_CONDITION.QUESTIONs").Where(p => p.PRODUCT_CODE == productCode).FirstOrDefault();

        product.ProductId = prod.PRODUCT_ID;
        product.ProductCode = prod.PRODUCT_CODE;
        product.ProductName = prod.PRODUCT_NAME;

        // go through coverage conditions
        covCondList = new List<CoverageCondition>();
        product.CoverageConditions = covCondList;
        foreach (COVERAGE_CONDITION cc in prod.COVERAGE_CONDITION)
        {
            covCond = new CoverageCondition();
            covCond.ConditionId = cc.COV_CONDITION_ID;
            covCond.ConditionCode = cc.COV_CONDITION_CODE;
            covCond.ConditionName = cc.COV_CONDITION_NAME;
            covCondList.Add(covCond);

            // go through questions for each coverage condtion, if any
            questList = new List<Question>();
            covCond.Questions = questList;
            foreach (QUESTION q in cc.QUESTIONs)
            {
                question = new Question();
                question.QuestionId = q.QUESTION_ID;
                question.QuestionCode = q.QUESTION_CODE;
                question.QuestionText = q.QUESTION_TEXT;
                questList.Add(question);
            }
        }