C# 用于在查询中快速加载的动态Include语句-EF 4.3.1

C# 用于在查询中快速加载的动态Include语句-EF 4.3.1,c#,entity-framework,c#-4.0,entity-framework-4.1,entity-framework-4.3,C#,Entity Framework,C# 4.0,Entity Framework 4.1,Entity Framework 4.3,我有这个方法: public CampaignCreative GetCampaignCreativeById(int id) { using (var db = GetContext()) { return db.CampaignCreatives .Include("Placement") .Include("Crea

我有这个方法:

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”。存在显式转换。是否缺少强制转换

有人知道如何使列表包含动态的吗

谢谢

使查询变量可查询:

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

使用IQueryable而不是var给编译器一个提示也可以

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

使用var时,编译器会推断DbSet for query,它比Include返回的类型更具体,Include是DbQuery=DbSet实现IQueryable的基类,因此您不能再将结果分配给查询变量。因此,query=query.Includeinclude行出现编译器错误。

我更喜欢定义include的非字符串表达方式。主要是因为它不依赖于魔术弦

对于示例代码,它将如下所示:

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();
    }
}
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
);
为了使这些动态化,您可以这样做:

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

我编写此方法是为了根据实体的类型动态检索任何一组实体。我使用IDbEntity接口提供了一个有效的键来搜索所有类中的用户ID。 Util.GetInverseProperties方法用于获取Include语句中所需的属性

public IEnumerable GetItemsstring用户标识,其中T:class,IDbEntity { var query=db.Set.Wherel=>l.UserId==UserId; var props=Util.GetInverseProperties; foreach变量包含在props中 query=query.Includeinclude.Name; 返回查询 .阿斯诺特拉克 托利斯特先生; } 公共接口实体 { 公共字符串用户标识{get;set;} } 公共静态列表GetInverseProperties { 返回类型 .GetProperties .Wherep=>Attribute.IsDefinedp,typeofInversePropertyAttribute 托利斯特先生; }
我不明白。IQueryable没有Include方法。此解决方案无法编译。在某些项目中,此解决方案会导致编译错误。使用System.Data.Entity添加;要访问iQueryTable上的Include扩展方法,这不适用于EF4.0。缺少Include ExtensionQuerable没有EF4.0的Include扩展。对于EF4.0,您相反地将IQuerable强制转换为ObjectQuery。然后你可以包括细节。我在上面说过,但我会在这里说,以防有人错过它:一些项目,你会得到这个解决方案编译错误。使用System.Data.Entity添加;访问IQueryable上的Include扩展方法。此答案应该是已检查的答案。对于泛型类型上的EF强类型导航属性,我发现它非常有用。是否有一种方法可以使用相同的includes方法实现左连接或右连接。作为参考,我包括我的帖子链接,谢谢。我做了一个插件,就是这样做的,这里是链接