16

私はこの方法を持っています:

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();
            }
        }

インクルードのリストを動的にしたいと思います。私は試した:

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();                    
            }
        }

しかし、それはコンパイルされませんでした。このエラーが発生しました:

タイプ 'System.Data.Entity.Infrastructure.DbQuery' を 'System.Data.Entity.DbSet' に暗黙的に変換することはできません。明示的な変換が存在します (キャストがありませんか?)

インクルードのリストを動的にする方法を知っている人はいますか?

ありがとう

4

4 に答える 4

37

私は、インクルードを定義する文字列以外の表現方法の方が好きです。主な理由は、魔法の糸に依存していないためです。

サンプル コードでは、次のようになります。

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();
    }
}

これらを動的にするには、次のようにします。

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);
    }
}

これは次のように使用されます:

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
);
于 2013-10-04T11:09:16.917 に答える
15

変数をqueryクエリ可能にします。

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();                    
    }
}
于 2012-04-03T20:46:49.010 に答える
2

IQueryable<CampaignCreative>の代わりにを使用してコンパイラにヒントを与えるvarことも機能します。

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

varコンパイラーを使用すると、によって返される型((=基本クラスの)を実装する)よりも具体的な推論DbSet<T>が行われるため、結果を変数に割り当てることができなくなります。したがって、行のコンパイラエラー。queryIncludeDbQuery<T>DbSet<T>IQueryable<T>queryquery = query.Include(include)

于 2012-04-03T22:27:25.887 に答える