Reputation: 38033
I struggled for hours to find a solution to this. I'm posting as a question and answer for the benefit of others who may come after me.
I wanted to make a cross join between two tables. For demonstration purposes, let's say I want to print a matrix of people and dishes, so I can fill in how much each person likes each food
var q = from p in db.People
from d in db.Dishes
select new
{
PersonID = p.ID,
PersonName = p.Name,
DishID = d.ID,
DishName = d.Name
};
But when I executed this query, I got an exception:
Unable to create a constant value of type 'MyDomain.Dish'. Only primitive types or enumeration types are supported in this context.
I searched all over for references to this error, and found lots of references to Contains()
conditions... but I didn't have any Contains()
conditions in my query.
I tried reversing the order of the tables:
var q = from d in db.Dishes
from p in db.People
...
And the error, too, got reversed!
Unable to create a constant value of type 'MyDomain.Person'. Only primitive types or enumeration types are supported in this context.
What's more, I discovered that if I first pulled my Person
and Dish
tables into memory using .ToList(), it worked fine, thus:
var q = from d in db.Dishes.ToList()
from p in db.People.ToList()
...
But it's very wasteful to load two entire tables into memory, when all I'm interested in is the ID and Name fields of each.
So how to make this cross join work in a single query?
Upvotes: 2
Views: 137
Reputation: 38033
The multiple references to the Contains()
condition tipped me off that the first table was somehow trying to do a "contains" on the second one. So instead of doing a cross join, I did an inner join on a universally true condition:
var q = from p in db.People
join d in db.Dishes on 1 equals 1
select new
{
PersonID = p.ID,
PersonName = p.Name,
DishID = d.ID,
DishName = d.Name
};
Voila! EF is happy and the cross join comes back without any complaints.
Upvotes: 3