Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq returns list or single object

I have a Linq to Entities query like this one:

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == (int)pCategory
              select r;

Usually, I use the code below to check if some results are returned:

if (results.Count() > 0)
{
    return new oMachineRevision(results.First().IdMachineRevision);
}

However, I'm getting NotSupportedException in the if condition.

The error message is: Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

Note that pCategory is an Enum type.

like image 637
Nelson Reis Avatar asked Dec 30 '08 11:12

Nelson Reis


4 Answers

EDIT: Based on your update, the error may be related to an enum in your entity class. See this blog entry for more information and a work-around. I'm leaving my original answer as an improvement on your query syntax.

Try doing the selection of the first entity in the query itself using FirstOrDefault and then check if the result is null.

int compareCategory = (int)pCategory; // just a guess
var result = (from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == compareCategory
              select r).FirstOrDefault();

if (result != null)
{
     return new oMachineRevision(result.IdMachineRevision);
}
like image 97
tvanfosson Avatar answered Nov 15 '22 20:11

tvanfosson


Why not just use FirstOrDefault() instead, and check for null? I can't see the benefit in querying for the count and then taking the first element.

like image 27
Jon Skeet Avatar answered Nov 15 '22 22:11

Jon Skeet


In the standard implementation of linq, the operators "select" and "where" map to methods that return an IEnumerable or IQueryable. So standard linq methods when used should always return an IEnumerable from your query not a single object.

But linq methods that are candidates for the linq operators are not restricted to methods returning IEnumerables, any method returning anything can be chosen.

In case you have instance methods named "Select" and "Where" that return a single object or extensions methods that are specific to your class and return a single object those will be used instead of the standard linq ones.

My guess is that either a "Select" or "Where" method defined in your class is making linq return a single value instead of a IEnumerable<T>.

like image 2
Pop Catalin Avatar answered Nov 15 '22 20:11

Pop Catalin


I didn't know different anonymous objects would be created depending on the query result. I guess they just wanted results to be of type IEnumerable

How about using a foreach?

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == pCategory
              select r;

foreach( var r in results )
{
    yield return new oMachineRevision( r.IdMachineRevision );
}
like image 1
Trap Avatar answered Nov 15 '22 21:11

Trap