我使用此代码:
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子句,有没有办法实现这个目的?
答案 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”。