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!
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.
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();
Please look at following solution. You can separate fields for List and IEnumerable in your class:
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; }
}
So you have to use ThingsForLinq in EF Linq queries:
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();
And use Things later:
myClass.Things.Add(...)
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);
}
}
精彩评论