在Dynamic Lambda Expression中获取Count()属性

时间:2014-04-30 14:45:26

标签: c# asp.net-mvc-4 dynamic lambda

我几乎得到了我需要的东西,但只有一个地方我坚持了。我需要在Lambda Expression中动态构建 fileCount = c.CPNDocs.Count()。代码如下所示,我正在使用它来构建Dynamic Lambda Expression。

var dColDefaultList = new List<String>() { "Download", "I_ID", "C_TYP", "C_LST_ACT" };       // <------- Columns I need in Lambdas Expression

ParameterExpression cParam = Expression.Parameter(typeof(CPNDBase), "c");

NewExpression newExp = Expression.New(typeof(DTDataModel));

List<MemberBinding> bindings = new List<MemberBinding>();

foreach (String sCol in dColDefaultList)
{
    if (!String.Equals(sCol, "Download")) {
        bindings.Add(GetMemberBinding(sCol, cParam, sCol));
    }
    else
    {
        bindings.Add(GetMemberBinding("fileCount", cParam, "CPNDocs.Count()")); //   <-------need count of rows return from CPNDocs(Different Table) is a Object I recieved from     Entity Relatioship
    }
}

MemberInitExpression memberInitExpression =         System.Linq.Expressions.Expression.MemberInit(newExp, bindings);

Expression<Func<CPNDBase, DTDataModel>> selector = (Expression<Func<CPNDBase,   DTDataModel>>)BinaryExpression.Lambda(memberInitExpression, cParam);

// selector  will be selector = {c => new DTDataModel() {fileCount = c.CPNDocs, I_ID =   c.I_ID, C_TYP = c.C_TYP, C_LST_ACT = c.C_LST_ACT }}
// but I Need selector = {c => new DTDataModel() {fileCount = c.CPNDocs.Count(), I_ID = c.I_ID, C_TYP = c.C_TYP, C_LST_ACT = c.C_LST_ACT }}

// Question is How can I make fileCount = c.CPNDocs.Count() ?

var resultLm = finalFilteredCPNData.AsQueryable<CPNDBase>().Select(selector);

以上方法定义如下:

static MemberBinding GetMemberBinding(string property, ParameterExpression param,  string column)
{
    MemberInfo memberInfo = typeof(DTDataModel).GetMember(property)[0];
    MemberExpression memberExpression = LambdaExpression.PropertyOrField(param, column);
    return System.Linq.Expressions.Expression.Bind(memberInfo, memberExpression);
}

有人知道我该怎么办?

1 个答案:

答案 0 :(得分:1)

Count()不是属性。它是在静态类中实现的扩展方法。这种扩展方法在几个地方实现。正确的位置取决于您继承的类。要找到正确的位置,请使用Visual Studio的“转到定义”功能。

e.g。对于IQueryable.Count(),扩展方法由System.Linq.Queryable静态类实现,如此处所示→http://referencesource.microsoft.com/#System.Core/System/Linq/IQueryable.cs

因此,为了对表达式进行编码,您需要对扩展方法的调用进行编码。

在微软发布的原型中很早就展示了从字符串生成表达式树的更简单的方法。介绍性文章可用,例如在Dynamic Expressions and Queries in LINQ

我们成功使用自动“string to linq”引擎的原始源的修改版本,它简化了开发。通过检查System.Linq.Dynamic的源代码,您可以找到如何编码表达式的确切方法。链接到通过NuGet可获得的原始源代码,例如,在Stack Overflow文章Dynamic LINQ - Is There A .NET 4 Version?