IQueryable, Where, Guid e
-
03-07-2019 - |
Domanda
Sto lavorando attraverso il codice MVC Storefront e sto cercando di seguire il percorso di un repository, un servizio e un modello che è poco, al di fuori del contesto dbml / data. In realtà è abbastanza facile da seguire, fino a quando non ho iniziato a scrivere test e le cose sono fallite in un modo che non capisco.
Nel mio caso, la chiave primaria è un IDidentificatore anziché un campo int. Il repository restituisce un IQueryable:
public IQueryable<Restaurant> All()
{
return from r in _context.Restaurants select new Restaurant(r.Id)
{
Name = r.Name
};
}
In questo caso, Restaurant è ovviamente un Models.Restaurant e non _context.Restaurants.Restaurant.
Filtraggio nella classe di servizio (o nei test dell'unità repository) su All (), funziona esattamente come previsto:
var results = Repository.All().Where(r => r.Name == "BW<3").ToList();
Funziona bene, ha un Model.Restaurant. Ora, se provo le stesse cose con il pkid:
var results = Repository.All().Where(r => r.Id == new Guid("088ec7f4-63e8-4e3a-902f-fc6240df0a4b")).ToList();
Se fallisce con:
The member 'BurningPlate.Models.Restaurant.Id' has no supported translation to SQL.
Se visti alcuni post simili in cui la gente dice che è perché r = > r.Id is [Model.Restaurants] è un livello di classe di cui il livello linq2sql non è a conoscenza. Per me, ciò significa che neanche la prima versione dovrebbe funzionare. Naturalmente, se il mio pk è un int, funziona perfettamente.
Cosa sta succedendo davvero qui? Dio lo sa, non è molto intuitivo avere un lavoro e uno non funziona. Cosa sto fraintendendo?
Soluzione
Penso che il problema qui sia dovuto all'utilizzo di un sovraccarico del costruttore e alla previsione di compilazione della query. Quando si esegue una proiezione come questa, è necessario inserire tutte le cose che si desidera inserire nella query di proiezione nella vera proiezione stessa. Altrimenti Linq non lo includerà nella query SQL.
Quindi, riscrivi i tuoi bit in questo modo:
return from r in _context.Restaurants select new Restaurant()
{
Id=r.Id,
Name = r.Name
};
Questo dovrebbe risolverlo.
Altri suggerimenti
Non avendo effettivamente digitato questo codice, hai provato
var results = Repository.All (). Where (r = > r.Id.Equals (nuovo Guid (" 088ec7f4-63e8-4e3a-902f-fc6240df0a4b ")). ToList ()
Ninja
questo probabilmente ha a che fare con il fatto che stai provando a creare un'istanza della guida nella query e penso che LINQ to SQL stia cercando di convertirlo in codice SQL effettivo prima che l'oggetto venga creato.
Prova a creare un'istanza prima della query e non sulla query.