Ciao,
usa Any che non capisco esattamente a cosa corrisponda
Una premessa: non tutte le tecniche che usi in una query SQL hanno una corrispondenza tale-e-quale in Linq to Entities (e viceversa).
Linq to Entities è uno strumento che usi per interrogare il tuo modello concettuale che consiste di grafi di oggetti e che può avvalersi di ereditarietà, ovvero concetti che non esistono nel mondo relazionale.
Va appreso metodicamente e senza cercare di "tradurre" da query SQL esistenti, altrimenti rischi di trovarti facilmente in situazioni ingarbugliate
come questa.
La query che hai scritto dovrebbe funzionare. Con l'uso di Any hai imposto che l'obj, per essere restituito come risultato, debba possedere un'autorizzazione per l'utente (e l'oggetto in questione).
Con una prima semplificazione diventerebbe così:
var objs = from obj in ctx.MyObjs
where obj.Authorization.Any(a => a.UserGuid==user.Guid) && a.ObjectGuid==obj.Guid && obj.Status == status.ToString()
select obj;
Commenti:
- L'Include non è necessario se non ti interessa che i dati delle autorizzazioni vengano restituite dalla query. (Se non le visualizzi a schermo, non ti serve recuperarle con l'Include)
- Ho spostato il filtro su a.ObjectGuid fuori dall'Any. Infatti da obj.Authorization accedi già alle sole authorization di quell'oggetto
- Ho tolto anche l'order by dato che *mi sembra* tu stia filtrando per la chiave primaria di obj, e perciò il risultato restituito sarà al massimo 1.
La query Linq to Entities si poteva scrivere anche in questo modo. Forse produrrà una query SQL più simile all'esempio che hai postato. Affinché funzioni, è necessario che tu abbia creato una proprietà di navigazione che ti porta da Authorization verso MyObj. Assumo anche che esista un DbSet<Atuhorization> chiamato Authorizations nel tuo DbContext.
var objs = from authorization in ctx.Authorizations
where authorization.UserGuid==user.Guid && authorization.ObjectGuid==obj.Guid && authorization.MyObj.Status==status.ToString()
select authorization.MyObj;
La query qui sopra interroga il set delle Authorizations, filtrando per il guid di User e MyObj e alla fine restituisce MyObj.
Come faccio inoltre a sapere se una query Linq è scritta in modo da performare bene?
Entity Framework ti dà modo di tracciare tutte le query e i comandi inviati al database impostando un'Action alla proprietà Database.Log del DbContext.
using (var context = new TuoDbContext())
{
context.Database.Log = testo => {
//Scrivi il contenuto di testo da qualche parte.
//Ad esempio con questo codice vedrai apparire le query
//nel riquadro "Output" di Visual Studio
System.Diagnostics.Debug.WriteLine(testo);
};
// qui il resto del codice
}
Leggi anche qui:
https://msdn.microsoft.com/en-us/data/dn469464.aspx#Log
In SQL ho pieno controllo di quello che scrivo e posso ottimizzare le query anche in base agli indici creati...in Linq come faccio a fare qualcosa di simile?
Anche con Entity Framework puoi decidere quali indici creare e su quali colonne. Vedi qui:
http://www.entityframeworktutorial.net/entityframework6/index-attribute-in-code-first.aspxEsiste un modo di farlo anche da interfaccia fluente.
http://stackoverflow.com/questions/23892553/creating-unique-index-with-entity-framework-6-1-fluent-api#answers-headerMan mano che acquisisci esperienza con le query LINQ to Entities, imparerai naturalmente a scrivere query ottimizzate e non dovrai più controllare così spesso il log prodotto dal DbContext. Col tempo imparerai a fidarti di Entity Framework; nel frattempo è normale essere diffidenti, soprattutto se non hai mai usato un ORM prima d'ora.
mi sembra quasi di "dover incrociare le dita".
Accelera il tuo apprendimento procurandoti un libro. Ti consiglio in particolare quello di Julie Lerman su Code First.
ciao,
Moreno
Modificato da BrightSoul il 25 settembre 2016 13.24 -