计算foreach循环内的多个字段/列

时间:2018-04-12 12:53:30

标签: c# linq

我使用此代码:

var mydynlist = AsDynamic(App.Data["mydynlistsource"]);

foreach(var q in mydynlist){
    ...
            <td>@q.a1</td>
            <td>@q.b1</td>
            <td>@q.b2</td>
            <td>@q.b3</td>
    ...
}

并正确地用

替换值
    <td>s</td>
    <td>n</td>
    <td>na/td>
    <td>s</td>

每个字段可以采用值“s”,“n”或“na”。我使用这4个例子,但有超过50个字段。

我需要添加一个新行,其中包含“s”值的字段总数。 我尝试使用这个在循环外工作的解决方案:

foreach(var q in auditorias){
    ...
            <td>@q.SelectMany(i=> new string[] {i.a1, i.b1, i.b2, i.b3 })
                  .Count(i => i == "s")</td>
            <td>@q.a1</td>
            <td>@q.b1</td>
            <td>@q.b2</td>
            <td>@q.b3</td>
    ...
}

但是这会给出错误:“不能将lambda表达式用作动态调度操作的参数,而不先将其转换为委托或表达式树类型。”

如果不为每个字段使用if子句,有没有办法实现这个目的?

1 个答案:

答案 0 :(得分:0)

可能不会那么快,但您可以使用反射解决LINQ的dynamic限制。

<td>@(((Type)q.GetType()).GetProperties().Select(m => (object)m.GetValue(q)).Count(m => "s".Equals(m)))</td>

你可以用扩展方法包装它:

public static int GetCount(this object q, string match)
{
    var values = ((Type)q.GetType()).GetProperties()
        .Select(m => (object)m.GetValue(q))
        .Count(m => match.Equals(m));
    return values;
}

如果您需要在任何地方重复使用,请稍微简化您的通话:

<td>@(q as object).GetCount("s")</td>

此代码仅适用于查找动态对象的属性。如果动态对象使用字段而不是属性,则使用GetFields()方法(或修改扩展方法以合并2个值。

只需调用GetFields()/ GetProperties()方法一次就可以获得一些性能提升,但这假设所有动态值都是相同的结构。否则,如果第一个动态对象缺少它没有使用的属性(例如“b2”),那么具有该属性的其他动态对象将无法在“b2”属性中找到“s”。