LINQ to Entities投影嵌套列表

时间:2010-05-28 16:53:50

标签: c# entity-framework linq-to-entities entity

假设这些对象......

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

如何使用下面的投影执行LINQ to Entities Query,它会给我一个List?这与IEnumerable工作正常(假设MyClass.Things是IEnumerable,但我需要使用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();

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:14)

你没有。你必须在L2O中做这个部分。

所以你可以这样做:

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

在一个查询中无法执行此操作。

答案 1 :(得分:1)

我不确定你究竟在询问什么,但是List<T>确实实现了IEnumerable<T>(这只是一个可枚举序列的接口)。

将执行投影并将Things设为List而不是IEnumerable的代码将使用ToList()运算符,该运算符从任何List<T>创建IEnumerable<T>

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

答案 2 :(得分:0)

请看以下解决方案。您可以在类中为List和IEnumerable分隔字段:

class MyClass
{
    ...

    List<MyOtherClass> m_Things = new List<MyOtherClass>();
    public List<MyOtherClass> Things
    {
        get
        {
            if (ThingsForLinq != null)
            {
                m_Things = ThingsForLinq.ToList();
                ThingsForLinq = null;
            }
            return m_Things;
        }
        set
        {
            m_Things = value;
        }
    }

    public IEnumerable<MyOtherClass> ThingsForLinq { get; set; }
}

所以你必须在EF Linq查询中使用ThingsForLinq:

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

稍后再使用:

myClass.Things.Add(...)

答案 3 :(得分:-2)

这个答案很有帮助,但这就是我这样做的方法。这将转换为POCO,并且可以支持无限制的嵌套列表。非常简单但功能强大:

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