LINQ to Entities投影嵌套列表

假设这些对象……

class MyClass { int ID {get;set;} string Name {get;set;} List 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(); 

在此先感谢您的帮助!

你没有。 你必须在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(); 

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

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

一个代码将执行您的投影并使Things为List而不是IEnumerable将使用ToList()运算符,该运算符从任何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 }).ToList() }).FirstOrDefault(); 

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

 class MyClass { ... List m_Things = new List(); public List Things { get { if (ThingsForLinq != null) { m_Things = ThingsForLinq.ToList(); ThingsForLinq = null; } return m_Things; } set { m_Things = value; } } public IEnumerable 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(); 

并在以后使用Things:

 myClass.Things.Add(...) 

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

 Product product = new Product(); List covCondList = null; CoverageCondition covCond = null; Question question = null; List 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(); 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(); 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); } }