9

ho questo metodo:dinamica Includere dichiarazioni a eager loading in una query - EF 4.3.1

public CampaignCreative GetCampaignCreativeById(int id) 
     { 
      using (var db = GetContext()) 
      { 
       return db.CampaignCreatives 
        .Include("Placement") 
        .Include("CreativeType")      
        .Include("Campaign") 
        .Include("Campaign.Handshake") 
        .Include("Campaign.Handshake.Agency") 
        .Include("Campaign.Product") 
        .AsNoTracking() 
        .Where(x => x.Id.Equals(id)).FirstOrDefault(); 
      } 
     } 

vorrei fare l'elenco delle Include dinamica. Ho provato:

public CampaignCreative GetCampaignCreativeById(int id, string[] includes) 
     { 
      using (var db = GetContext()) 
      { 
       var query = db.CampaignCreatives; 

       foreach (string include in includes) 
       { 
        query = query.Include(include); 
       } 

       return query.AsNoTracking() 
        .Where(x => x.Id.Equals(id)).FirstOrDefault();      
      } 
     } 

Ma non è stato compilato. Ho ricevuto questo errore:

Impossibile convertire implicitamente il tipo 'System.Data.Entity.Infrastructure.DbQuery' in 'System.Data.Entity.DbSet'. Esiste una conversione esplicita (ti manca un cast?)

Qualcuno sa come rendere dinamico l'elenco di include?

Grazie

+0

Ho fatto un plugin che fa proprio questo qui è il link https://www.codeproject.com/Tips/1205294/Entity-Framework-Dynamic-Include-Hier archy –

risposta

9

Fai la variabile query queryable:

public CampaignCreative GetCampaignCreativeById(int id, string[] includes) 
{ 
    using (var db = GetContext()) 
    { 
     var query = db.CampaignCreatives.AsQueryable(); 
     foreach (string include in includes) 
     { 
      query = query.Include(include); 
     } 

     return query 
      .AsNoTracking() 
      .Where(x => x.Id.Equals(id)) 
      .FirstOrDefault();      
    } 
} 
+0

Quale versione di EntityFramework richiede? – cmour

+0

Non capisco. IQueryable non ha alcun metodo di inclusione. Questo non viene compilato. – dudeNumber4

+0

Alcuni progetti riceveranno un errore di compilazione con questa soluzione. Aggiungi usando System.Data.Entity; per accedere al metodo di estensione Includi su IQueryable –

1

Dare il compilatore un suggerimento utilizzando IQueryable<CampaignCreative> invece di var funzionerà anche.

IQueryable<CampaignCreative> query = db.CampaignCreatives; 
// or 
DbQuery<CampaignCreative> query = db.CampaignCreatives; 

Quando si utilizza var il compilatore deduce DbSet<T> per query che è più specifico del tipo restituito da Include (che è DbQuery<T> (= classe base di DbSet<T>) attuazione IQueryable<T>), quindi non è possibile assegnare il risultato la variabile query più. Quindi l'errore del compilatore sulla riga query = query.Include(include).

24

Sono più appassionato del modo espressivo non stringa di definire include. Principalmente perché non si basa su stringhe magiche.

Per il codice di esempio, sarebbe simile a questa:

public CampaignCreative GetCampaignCreativeById(int id) { 
    using (var db = GetContext()) { 
     return db.CampaignCreatives 
      .Include(cc => cc.Placement) 
      .Include(cc => cc.CreativeType)      
      .Include(cc => cc.Campaign.Select(c => 
       c.Handshake.Select(h => h.Agency))) 
      .Include(cc => cc.Campaign.Select(c => c.Product) 
      .AsNoTracking() 
      .Where(x => x.Id.Equals(id)) 
      .FirstOrDefault(); 
    } 
} 

E per rendere quelli dinamici, questo è come lo fai:

public CampaignCreative GetCampaignCreativeById(
    int id, 
    params Expression<Func<T, object>>[] includes 
) { 
    using (var db = GetContext()) { 
     var query = db.CampaignCreatives; 
     return includes 
      .Aggregate(
       query.AsQueryable(), 
       (current, include) => current.Include(include) 
      ) 
      .FirstOrDefault(e => e.Id == id); 
    } 
} 

che viene utilizzato in questo modo:

var c = dataService.GetCampaignCreativeById(
    1, 
    cc => cc.Placement, 
    cc => cc.CreativeType, 
    cc => cc.Campaign.Select(c => c.Handshake.Select(h => h.Agency)), 
    cc => cc.Campaign.Select(c => c.Product 
); 
+0

È davvero bello! – pomeroy

+1

L'ho detto sopra ma lo dirò qui nel caso qualcuno lo mancasse: alcuni progetti riceveranno un errore di compilazione con questa soluzione. Aggiungi usando System.Data.Entity; per accedere al metodo di estensione Includi su IQueryable. –

+1

molto bello, esattamente quello che stavo cercando di acheive. – Kramer00

Problemi correlati