Nested query in entity framework
I had this error too. I had code like this:
var Games = context.Games.Select(a => new GameModel
{
Members = (!filters.GetDatailedDataToo ? null : new List<MemberModel>())
};
This error occurs when null
is used in ? :
operation.
This is not that case, written up here, but I've wasted lot of time, I think anyone uses this case, who searches this error text..
You're overestimating the power of LINQ translation to SQL. Not everything is translatable and there is no compiler warning for that due to the way LINQ works.
Nested collections are usually either a) not supported or b) end up in horrible SELECT N+1 queries. What you ask EF to do is to return an object tree. SQL does not support tree like results so you run into the object-relational impedance mismatch and it hurts.
I advise you to fetch the nested collection data as a second, completely separate query. That allows you more control and is guaranteed to work.
As a non-essential side-note, you will probably not be able to convince EF to use the ?: operator over sequences. That is very hard to translate. Think how you would write this as SQL - very hard and convoluted.
It looks like Linq to EF doesn't support the following
context.Games.Select(g => new
{
Field = g.IsX? queryable1 : queryable2
});
But, here's a hack you can use to get it to work:
context.Games.Select(g => new
{
Field = queryable1.Where(q => g.IsX)
.Concat(queryable2.Where(q => !g.IsX))
});
I faced the same problem. The solution was to load both results and determine what to use after the query (I know it has performance downside), but at least you can do it temporarily if deadline attacks you:
At the LINQ side
var Games = context.Games.Select(a => new GameModel
{
// carries type1 results
Members = a.UsersInGames.Where(b => b.GameID == a.ID && b.StatusID == 1).Select(c => new Member
{
ID = c.UserID,
email = c.UserInfo.EmailAddress,
screenName = c.UserInfo.ScreenName
})),
//You need to create this temporary carrier to carry type 2 results
MembersOfType2 = a.Teams.Where(b => b.GameID == a.ID).SelectMany(b => b.UsersInTeams.Where(c => c.StatusID == 1)).Select(d => new Member
{
ID = d.UserID,
email = d.UserInfo.EmailAddress,
screenName = d.UserInfo.ScreenName
})))
})
}
After that you may loop Games
and make the assignment Members = MembersOfType2
if Type == 1
for a certain game.