2016-02-08 21 views
6

Nel sottotitolato cerco di recuperare i dati usando Anonymous Projection e vorrei non tracciare il entities che viene recuperato.Il framework Entity `AsNoTracking` non funziona con la proiezione anonima

Nota: ho già passati attraverso domanda stack esistente, ma in grado di trovare una soluzione di lavoro per me

using (var db = new Entities()) 
{ 
    db.Configuration.LazyLoadingEnabled = false; 
    db.Configuration.ProxyCreationEnabled = false; 

    var myprojection = db.Table1 
         .AsNoTracking() 
         .Include(gh=>gh.Table2) //Update 
         .Include(gh=>gh.Table3) //Update 
         .Select(x => new 
         { 
          table1= x, 
          table2= x.Table2.Where(g => Some Condition), 

          table3= x.Table3.Where(g=>Some Condition) 
         }) 
         .ToList(); 

    var result = myprojection.Select(g =>g.table1).FirstOrDefault(); 

} 

Quando uso AsNoTracking() dati dalle tabelle interne (table2,3) è persa durante la conversione a questa linea var result = myprojection.Select(g =>g.table1).FirstOrDefault();

Modifica

Se rimuovo AsNoTracking(), tutto funziona correttamente.

1) Come utilizzare projection e AsNoTracking in Entity Framework correttamente?

2) Qualsiasi altra opzione per rimuovere il tracciamento di questa query?

Esistono soluzioni alternative?

+0

Perché hai impostato LazyLoadingEnabled e ProxyCreationEnabled su false? –

+0

Ho sia 'WCF' che una connessione diretta al database. Quindi ci sarà una serializzazione circolare se abilita il loadloading – Eldho

+0

Dovrai usare inner inner invece se vuoi filtrare quelle tabelle –

risposta

0

Forse si può provare in questo modo:

using (var db = new Entities()) 
    { 
     db.Configuration.LazyLoadingEnabled = false; 
     db.Configuration.ProxyCreationEnabled = false; 

     var myprojection = db.Table1 
          //.AsNoTracking() //remove.AsNoTracking() from here 
          .Select(x => new 
          { 
           table1= x, 
           table2= x.Table2.Where(g => Some Condition), 
           table3= x.Table3.Where(g=>Some Condition) 
          }) 
          .AsNoTracking()//add .AsNoTracking() here 
          .ToList();  

     var result = myprojection.Select(g =>g.table1).FirstOrDefault();  
    } 

NOTA: I dont provare questo. Solo un'idea, spero che questo aiuta a voi

+0

fammi controllare e aggiornarti. – Eldho

+0

Non funziona, sempre lo stesso – Eldho

+0

Penso che non funzionerà. _AsNoTracking_ non modificherà _Table1_ ma restituirà "una nuova query in cui le entità restituite non verranno memorizzate nella cache in System.Data.Entity.DbContext." –

1

Prima di tutto, non ha senso utilizzare db.Configuration.ProxyCreationEnabled = false e AsNoTracking() allo stesso tempo.

Se si utilizza db.Configuration.ProxyCreationEnabled = false, il rilevamento delle modifiche verrà disattivato per tutte le query.

Ma il problema con le tabelle interne 2 e 3 non è causato da AsNoTracking().

db.Configuration.LazyLoadingEnabled = false; 
db.Configuration.ProxyCreationEnabled = false; 

Disattivare il caricamento lento e suppongo che sia buono per motivi di prestazioni. Se lo si accende, si otterrà il risultato previsto, ma Entity Framework effettuerà una query SQL aggiuntiva su Data Base per ogni riga nel risultato myprojection. Si dovrebbe meglio effettuare le seguenti operazioni:

using (var db = new Entities()) 
{ 
    db.Configuration.LazyLoadingEnabled = false; 
    db.Configuration.ProxyCreationEnabled = false; 

    var myprojection = db.Table1 
        .Include(x=>x.Table2).Include(x=>x.Table3) 
        .Select(x => new 
        { 
         table1= x, 
         table2= x.Table2.Where(g => Some Condition), 
         table3= x.Table3.Where(g=>Some Condition) 
        }) 
        .ToList(); 

    var result = myprojection.Select(g =>g.table1).FirstOrDefault(); 

} 

Utilizzando .Include(x=>x.Table2).Include(x=>x.Table3) nella query sarà forza Entity Framerwork per caricare legati Table2 e Table3 per un query per Data Base.

+0

Ancora non funziona, ho provato quelli. – Eldho

+1

Includi non funzionerà per le proiezioni personalizzate. Quindi i dati di 'Tabella2/3' non verranno caricati nella proprietà' table1'. Ma verrà caricato nelle proprietà 'table2' e' table3' senza 'Include'. – tenbits

1

Utilizzare ToList() per le proprietà di navigazione. Si noti che sarà ancora projekt nel DB.(EF6)

// .. 
table2 = x.Table2.Where(g => Some Condition).ToList(), 

Aggiornamento:

Con EF4 probabilmente è necessario mappare table2 manualmente:

table2 = x.Table2.Where(g => CONDITION).Select(x => new {Foo = x.Bar}), 
+0

Genera un'eccezione "LINQ su Entità non riconosce il metodo" – Eldho

+0

La tua espressione "Alcune condizioni" è semplice? Mentre 'ToList' funziona sicuramente in EF6. Prova a rimuovere la condizione, otterrai comunque l'eccezione? – tenbits

+0

Scusa se ho dimenticato di menzionare, sto usando EF4, La condizione è piuttosto semplice '(SomeVariable == SomeVariable && SomeBoolean)' – Eldho

0

Quando ho useAsNoTracking) dati dalle tabelle interne ((table2,3) viene perso durante la conversione su questa riga var result = myprojection.Select (g => g.table1) .FirstOrDefault();

Selezionando Table1, in un tipo anonimo non si avrà accesso a table2 o table3 sebbene le proprietà di navigazione siano esse non verranno mappate. Le entità ne perdono le relazioni quando si seleziona in un tipo anonimo è necessario selezionare la tabella due e tre o non estrarla in un tipo anonimo.

Basta mettere i wheres direttamente nella tabella quella in cui e quindi effettuare la chiamata

var myprojection = db.Table1.Join(db.Table2.Where(x => yourcondition), 
            t1 => t1.id, t2 => t2.t1id, (t1, t2) => t1); 

allora dovete fare un altro unirsi per table3

ma il vostro probabilmente meglio solo facendo la chiamata in due query

+0

Sto usando 'ef4' che non si sta compilando nel mio scenario. Qui 'Table1' to Table2 ha una relazione da 1 a molti. 'Impossibile convertire IEnumberable in bool exception' – Eldho

+0

Hold on ill update la mia risposta –

Problemi correlati