Linq returns a list or a single object

I have a Linq to Entities query like this:

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

I usually use the code below to check if any results are returned:

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

However, I get a NotSupportedException in if .

Error message: Unable to create a constant value of type "Closing Type". In this context, only primitive types (such as Int32, String, and Guid) are supported.

Note that pCategory is an Enum type.

+7
enums c # linq
source share
8 answers

EDIT . Based on your update, the error may be related to an enumeration in the entity class. See the blog post for more information and a workaround. I leave my original answer as an improvement in the query syntax.

Try selecting the first object in the query itself with 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); } 
+11
source share

Why not just use FirstOrDefault () instead and check for null? I do not see an advantage when requesting a counter, and then I take the first element.

+2
source share

In the standard linq implementation, the "select" and "where" operators map methods that return IEnumerable or IQueryable. Therefore, standard linq methods, when used, should always return IEnumerable from your request to more than one object.

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

If you have instance methods called Select and Where that return a single object or extension methods that are specific to your class and return a single object, they will be used instead of the standard linq.

My assumption is that either the "Select" or "Where" method defined in your class means that linq returns a single value instead of IEnumerable<T> .

+2
source share

I did not know that depending on the result of the request, different anonymous objects will be created. I think they just wanted the results to be IEnumerable.

How to use 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 ); } 
+1
source share

This also applies to all implicit types. I must admit, all the time I forget about it and about how I came across this post.

if you have

 class ClassA { ... private string value; ... public static implicit operator string(ClassA value) { return value.ToString(); } ... } 

you need to explicitly impose a class on the rider for comparison.

so i usually do it

  var myClassAStr = myClassA.ToString(); var x = (from a in entites where a.ValToCompare == myClassAStr select a).first(); // do stuff with x ... 
+1
source share

try using

 IENumerable<MachineRevision> results = from r in entities.MachineRevision ... 

instead.

I think this is var that is causing your problem.

0
source share

Edit:

Read error message. β€œIt is not possible to create a constant value of theβ€œ Closure type. ”Only primitive types (such as Int32, String, and Guid) are supported in this context.

One of these comparisons is for a type that is not int, string, or guid. I guess the Category.

 r.Machine.IdMachine == pIdMachine && r.Category == pCategory 

Interestingly, LinqToSql will allow this design. I do not know why LinqToEntities does not support this.

0
source share

I think you can also select the element that you need in a different, simpler way using lambda expressions.

 var result = entities.MachineRevision .Where(x => x.Machine.IdMachine == pIdMachine) .Where(y => y.Category == (int)pCategory) .FirstOrDefault(); if (result != null) { return new oMachineRevision(result.IdMachineRevision); } 

and then as usual

0
source share

All Articles