Shaul Behr
Shaul Behr

Reputation: 38033

"Unable to create a constant value of type [MyClass]. Only primitive types are supported in this context."

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

Answers (1)

Shaul Behr
Shaul Behr

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

Related Questions