2015-12-04 14 views
11

Sto provando a migrare il vecchio progetto da Linq2Sql a EF6 e ho ricevuto il seguente problema.Raccolte figli filtro EF 6

Questo progetto è multilingue (vale a dire tutti i testi hanno più di 1 traduzione) e ho seguente struttura db:

Example of DB tables

Qual è il modo migliore per ottenere tutti gli oggetti ExampleEntity1 con tutti i record LocalizedContent filtrati per ID lingua corrente?

posso caricare tutti gli oggetti ExampleEntity1 con tutti i record che utilizzano LocalizedContent seguente codice: dc.ExampleEntity1.Include(ee => ee.TextEntry.LocalizedContents);

In Linq2Sql posso filtrare i record LocalizedContent utilizzando loadOptions.AssociateWith ma non riesco a trovare alcuna soluzione per EF6.

Ho visto simili vecchie domande (pubblicate come 2-3 anni fa) e mi chiedo solo se esiste una soluzione per EF6. È una caratteristica molto importante per me perché ho decine di entità nel progetto e non voglio creare oggetti personalizzati per ogni query selezionata.

Ho anche trovato EntityFramework.DynamicFilters pacchetto NuGet che può aiutare con il mio problema, ma io preferirei usare la funzionalità EF6 "nativo", se possibile ..

+0

Un'opzione che viene in mente ma potrebbe non funzionare per la situazione: una funzione di database personalizzata che accetta l'ID lingua corrente e TextEntryId e restituisce i LocalizedContent corretti. Basta lanciarlo per sperare di accendere qualche idea. –

+0

solo per interesse ... perché non si sposta falso in textentry in localizedContent e si elimina il testo della tabella, questo non semplificherebbe le cose senza perdere nulla. come allora non dovresti passare attraverso un altro tavolo di collegamento .... che non riesco a vedere cosa aggiunge oltre a fakefield ... che potrebbe essere spostato su LocalizedContent ... – Seabizkit

+0

Se vuoi usare metodi nativi EF, Finiremo per intercettare gli alberi dei comandi dalla nuova API di intercettazione di EF6. Se lo fai, alla fine avrai reinventato EntityFramework.DynamicFilters. Vorrei andare per il pacchetto Nuget. –

risposta

1

Nota che non è attualmente possibile filtrare che relative alle entità caricate. Include includerà sempre tutte le entità correlate .

Msdn Reference

var result = dc.ExampleEntity1.Include(ee =>ee.TextEntry.LocalizedContents) 
       .Select(x=>new 
       { 
        //Try anonymous or a projection to your model. 
        //As this Select is IQuerable Extension it will execute in the data store and only retrieve filtered data. 
        exampleEntity = x, 
        localizedContetnt = x.TextEntry.LocalizedContents.Where(g=>g.Id==YourKey), 
       }).FirstOrDefault(); 

Si potrebbe provare anonymous projection per filtrare i contenuti nei soggetti inclusi

Entity Framework Team sta lavorando su questo si potrebbe esprimere il vostro voto here

Similar Answer

+0

Ho pensato a EF che tutti gli include dovevano essere specificati .. es. 'Dc.ExampleEntity1.Include (ee => ee.TextEntry) .Include (ee => ee.TextEntry.LocalizedContents)' hanno aggiunto questa capacità in quanto sa che ha bisogno della tabella liniking per accedere alla tabella LocalizedContents. – Seabizkit

-1

NON testato E non perfetto in termini di prestazioni a causa di come include opere ... Lo farei manualmente ma qui è un esempio di cosa si potrebbe fare.

var result = dc.ExampleEntity1 
      .Include(x => x.TextEntry) 
      .Include(x => x.TextEntry.LocalizedContents) 
      .Include(x => x.TextEntry.LocalizedContents.Local) 
      .Where(x => x.id == 'ExampleEntity1Key' 
         && x.TextEntity.LocalContent.Local.Id == 'Value' 
      ) 
      .FirstOrDefault(); 

Questo sarebbe finita con un oggetto di ExampleEntity1 con tutta la navigazione ansiosi caricato .... dove locale è abbinato a un id.

si potrebbe quindi ottenere il locale come ..

var listLocalsForExampleEnitity = result.TextEntry.LocalizedContents.Local.ToList(); 

o semplicemente chiamarli da dove mai in quanto sono già in mem.

Spero che questo aiuti

2

Se si desidera eseguire il filtraggio nella query al database, allora (come di EF6) è necessario utilizzare il Query method:

Il metodo Query consente di accedere alle query sottostante che Entity Framework utilizzerà durante il caricamento delle entità correlate. È quindi possibile utilizzare LINQ per applicare filtri alla query prima di eseguirlo con una chiamata a un metodo di estensione LINQ come ToList, carico, ecc

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts with the 'entity-framework' tag related to a given blog 
    context.Entry(blog) 
    .Collection(b => b.Posts) 
    .Query() 
    .Where(p => p.Tags.Contains("entity-framework") 
    .Load(); 

    // Load the posts with the 'entity-framework' tag related to a given blog 
    // using a string to specify the relationship 
    context.Entry(blog) 
    .Collection("Posts") 
    .Query() 
    .Where(p => p.Tags.Contains("entity-framework") 
    .Load(); 
} 

Tuttavia, lo svantaggio è evidente che si deve fare questo per ogni voce e ogni chiamata Load esegue una query sul database.

A meno che non sia un requisito difficile per te, sceglierei solo il caricamento di tutte le localizzazioni e semplicemente il filtro in memoria per utilizzare quello della lingua selezionata. Sono abbastanza sicuro che le prestazioni non saranno un problema.

+1

valore in questo ... su 1 da me. – Seabizkit

Problemi correlati