J’ai cette méthode:
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(); } }
Je voudrais faire la liste des inclus dynamic. J’ai essayé:
public CampaignCreative GetCampaignCreativeById(int id, ssortingng[] includes) { using (var db = GetContext()) { var query = db.CampaignCreatives; foreach (ssortingng include in includes) { query = query.Include(include); } return query.AsNoTracking() .Where(x => x.Id.Equals(id)).FirstOrDefault(); } }
Mais ça n’a pas compilé. J’ai eu cette erreur:
Impossible de convertir implicitement le type ‘System.Data.Entity.Infrastructure.DbQuery’ en ‘System.Data.Entity.DbSet’. Une conversion explicite existe (manque-t-il un casting?)
Est-ce que quelqu’un sait comment faire la liste des inclus dynamic?
Merci
Rendre la variable de query
interrogeable:
public CampaignCreative GetCampaignCreativeById(int id, ssortingng[] includes) { using (var db = GetContext()) { var query = db.CampaignCreatives.AsQueryable(); foreach (ssortingng include in includes) { query = query.Include(include); } return query .AsNoTracking() .Where(x => x.Id.Equals(id)) .FirstOrDefault(); } }
Je suis plus friand de la manière expressive non-ssortingng de définir des includes. Principalement parce qu’il ne repose pas sur des chaînes magiques.
Pour l’exemple de code, cela ressemblerait à ceci:
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(); } }
Et pour rendre ces dynamics dynamics, voici comment procéder:
public CampaignCreative GetCampaignCreativeById( int id, params Expression>[] includes ) { using (var db = GetContext()) { var query = db.CampaignCreatives; return includes .Aggregate( query.AsQueryable(), (current, include) => current.Include(include) ) .FirstOrDefault(e => e.Id == id); } }
Qui est utilisé comme ceci:
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 );
Donner un indice au compilateur en utilisant IQueryable
au lieu de var
fonctionnera également.
IQueryable query = db.CampaignCreatives; // or DbQuery query = db.CampaignCreatives;
En utilisant var
le compilateur déduit DbSet
pour une query
plus spécifique que le type renvoyé par Include
(qui est DbQuery
(= classe de base de DbSet
) implémentant IQueryable
), vous pouvez donc ‘ n’assignez plus le résultat à la variable de query
. D’où l’erreur du compilateur sur la ligne query = query.Include(include)
.