2013-04-04 13 views
5

Così ho preso qualcosa di simile:Lambda: clausola Where per la lista Includi

var myObj = db.SomeObject 
       .Include("Tasks") 
       .SingleOrDefault(x => x.Id == someObjectId); 

if (myObj != null) 
{ 
    myObj.Tasks = myObj.Tasks.OrderBy(x => x.Number).ToList(); 
} 

Qui voglio essere in grado di mettere una condizione (where) sulla mia includono, per esempio: .where task.IsDeleted == false

Quindi non ho trovato una soluzione.

Sono consapevole del fatto che potrei utilizzare il where insieme a dove ordino le attività, ma questo, tuttavia, non viene eseguito sul database ma utilizza la memoria. Voglio che funzioni sul database.

Qualcuno qui sa come posso farlo? In tal caso, c'è anche un modo per inserire la condizione order by nell'elenco delle attività incluse?

+0

non credo che sia possibile. – MarcinJuraszek

+1

Perché non hai appena ricevuto i compiti? E poi solo l'oggetto senza i compiti? – lahsrah

+1

@sylon: cosa intendi? – Tikkes

risposta

5

Qualcosa di simile, ti ripaga l'oggetto originale con la sua collezione figlio filtrata e ordinata.

SomeObject a = db.SomeObjects.Where(x => x.Id == someobjectid) 
         .Select(
          x => 
          new 
           { 
            someObject = x, 
            task = x.Tasks.Where(task => task.IsDeleted == false) 
               .OrderBy(task => whatever) 
           }) 
         .Select(x => x.someObject).Single(); 

In realtà è perdere la collezione di attività nell'ultimo di selezione in modo da poter fare questo:

SomeObject a = db.SomeObjects.Where(x => x.Id == someobjectid) 
         .Select(
          x => 
          new 
           { 
            someObject = x, 
            task = x.Tasks.Where(task => task.IsDeleted == false) 
               .OrderBy(task => whatever) 
           }); 
return a.FirstOrDefault().someObject; 
+0

In realtà funziona e mi restituisce effettivamente l'oggetto originale. tu! – Tikkes

2

La semplice risposta è: non puoi farlo.

Perché? Perché si richiede SomeObject.
Ciascuno restituito SomeObject contiene tutti i dati di riferimento, perché se non lo fosse non rappresenterebbe l'oggetto reale nel database.

+0

Quindi quale sarebbe un modo migliore di approccio? dato che ho per esempio 1000 compiti e non voglio caricarli tutti, poiché, diciamo, 600 hanno il flag 'IsDeleted' impostato su' true' – Tikkes

+0

@Tikkes: Penso che tu voglia una proiezione in quel caso. [Nicholas Butler] (http://stackoverflow.com/a/15810444/572644) mostra un esempio per EF. –

1

cosa circa ottenere separatamente:

var myObj = db.SomeObject 
       .SingleOrDefault(x => x.Id == someObjectId); 


var tasks = db.SomeObject 
       .Where(x => x.Id == someObjectId) 
       .SelectMany(x => x.Tasks) 
       .Where(x => !x.Deleted); 
5

per fare questo è EF, è necessario specificare una proiezione con una clausola Select.

Qualcosa di simile a questo otterrà solo i dati desiderati dal db:

var anonymous = db.SomeObject.Where(x => x.Id == someObjectId) 
    .Select(x => new 
    { 
     SomeObject = x, 
     Tasks = x.Tasks 
     .Where(o => !o.IsDeleted) 
     .OrderBy(o => ...) 
    } 
) 
    .SingleOrDefault() 
; 

Vi ritroverete con un'istanza del tipo anonimo, ma si può facilmente risolvere che fino sul client:

MyObject myObject = anonymous.SomeObject; 
myObject.Tasks = anonymous.Tasks; 
+0

Questo potrebbe funzionare, basta testare alcune cose con questo ancora. – Tikkes

+0

Funziona! Grazie! – Tikkes

+1

FYi: se non si desidera gestire oggetti anonimi, è possibile eseguirne il cast esplicito su un modello in Seleziona tramite .Select (x => new YourModelClass – ejhost