Domanda

Ho una query Linq to Entities come questa:

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

Di solito, utilizzo il codice seguente per verificare se vengono restituiti alcuni risultati:

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

Tuttavia, sto ricevendo NotSupportedException nella condizione if .

Il messaggio di errore è: Impossibile creare un valore costante di tipo 'Tipo di chiusura'. In questo contesto sono supportati solo i tipi primitivi ("come Int32, String e Guid").

Nota che pCategory è un tipo Enum.

È stato utile?

Soluzione

MODIFICA : in base al tuo aggiornamento, l'errore potrebbe essere correlato a un enum nella tua classe di entità. Vedi questo voce di blog per ulteriori informazioni e un'opera -in giro. Lascio la mia risposta originale come miglioramento della sintassi della tua query.

Prova a fare la selezione della prima entità nella query stessa usando FirstOrDefault e quindi controlla se il risultato è 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);
}

Altri suggerimenti

Perché non usare invece FirstOrDefault () e verificare la presenza di null? Non riesco a vedere il vantaggio nell'interrogare per il conteggio e quindi prendere il primo elemento.

Nell'implementazione standard di linq, gli operatori " selezionare " e " dove " mappare i metodi che restituiscono un IEnumerable o IQueryable. Quindi i metodi linq standard quando usati dovrebbero sempre restituire un IEnumerable dalla tua query non un singolo oggetto.

Ma i metodi linq che sono candidati per gli operatori linq non sono limitati ai metodi che restituiscono IEnumerables, qualsiasi metodo che restituisce qualcosa può essere scelto.

Nel caso in cui si disponga di metodi di istanza denominati " Selezionare " e " Dove " che restituiscono un singolo oggetto o metodi di estensioni specifici della tua classe e restituiscono un singolo oggetto che verranno utilizzati al posto di quelli linq standard.

La mia ipotesi è che sia un " Seleziona " oppure " Dove " il metodo definito nella tua classe sta facendo in modo che linq restituisca un valore singolo anziché IEnumerable<T>.

Non sapevo che sarebbero stati creati diversi oggetti anonimi a seconda del risultato della query. Immagino volessero solo che i risultati fossero di tipo IEnumerable

Che ne dici di usare un 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 );
}

Questo vale anche per tutti i tipi impliciti. Devo ammettere che continuo a dimenticare questo ed è così che mi sono imbattuto in questo post.

se hai

class ClassA {
               ...

               private string value;

               ...

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

              ...
}

devi esplicitamente lanciare la classe in astring per il confronto.

quindi di solito lo faccio

    var myClassAStr = myClassA.ToString();

    var x = (from a in entites where a.ValToCompare == myClassAStr select a).first();

// do stuff with x
    ...

prova a usare

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

, invece.

Penso che sia il var che sta causando il tuo problema.

Modifica:

Leggi il messaggio di errore. " Impossibile creare un valore costante di tipo 'Tipo di chiusura'. In questo contesto sono supportati solo i tipi primitivi ("come Int32, String e Guid"). & Quot;

Uno di questi confronti è con un tipo che non è int, string o guid. Sto indovinando la categoria.

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

È interessante notare che LinqToSql consentirà questa costruzione. Non so perché LinqToEntities non supporta questo.

Penso che potresti anche selezionare l'elemento che desideri in un altro modo più semplice usando le espressioni lambda.

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);
}

e quindi procedendo come faresti normalmente

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top