I have this LINQ-query:
// types...
LinkedList<WeightedItem> itemScores = new LinkedList<WeightedItem>();
var result = from i in _ctx.Items
join s in itemScores on i.Id equals s._id
orderby s._score descending
select new ItemSearchResult(i, s._score);
// this fails:
return result.ToList();
Which is generating this error:
Unable to create a constant value of type 'System.Collections.Generic.IEnumerable`1'.
Only primitive types ('such as Int32, String, and Guid') are supported in this context.
[EDIT] Here's the code of WeightedItem
:
public class WeightedItem
{
public int _id;
public decimal? _score;
public WeightedItem(int id, decimal? score)
{
_id = id;
_score = score;
}
}
Can you see what I've done wrong? The code compiles perfectly and both the _ctx.Items and itemScores contains proper values.
Just in case the table represented by _ctx.Items is not a big one and you don't care about loading all the table in memory and then filter it in memory, you can simply swap the order of the items in the join statement, as in the following snippet:
In the original statement the Queryable extension method was invoked:
while in the swapped one the Enumerable extension method is invoked:
so in the last statement the full _ctx.Items table is loaded in memory and then joined, via Linq to Objects, to the itemScores list (I don't know about LinkedList, I tried it with List).
I added this answer mainly because someone could type the join in the reverse order and have it work without even realize what is going to happen in the database.
I wouldn't suggest to join in this way, though it can be useful for backoffice applications whenever the involved tables are made up of few records and the application doesn't suffer a relevant performance worsening. This solution, after all, keeps the code cleaner.
Yes, it would compile fine - the problem is that it can't translate it into SQL. When you reference "local" values, the entity framework has to work out what to do with them when it needs to create a SQL query. It basically can't cope with doing a join between an in-memory collection and a database table.
One thing which might work would be to use
Contains
instead. I don't know whetherLinkedList<T>
will work for this, but I believeList<T>
does, at least in LINQ to SQL:Now that's doing a join in the in-memory query, which is somewhat unnecessary. You could instead use a dictionary:
You can't join between an in memory list and a queriable object. You need to do something like this: