C# where子句的动态lambda表达式
我有一个对象的动态列表,我在其中使用lambda expression where子句来过滤项。例如,只要考虑它有3个属性,Fo,Bar和BAZC# where子句的动态lambda表达式,c#,dynamic,lambda,dynamic-linq,C#,Dynamic,Lambda,Dynamic Linq,我有一个对象的动态列表,我在其中使用lambda expression where子句来过滤项。例如,只要考虑它有3个属性,Fo,Bar和BAZ class item // let this be current class in dynamic item list { bool foo; string bar; string baz; } 现在,如果我想过滤foo为false的项目列表,我可以使用下面的表达式 var filtered = itemList.Wher
class item // let this be current class in dynamic item list
{
bool foo;
string bar;
string baz;
}
现在,如果我想过滤foo为false的项目列表,我可以使用下面的表达式
var filtered = itemList.Where("!foo");
我甚至可以按字符串值筛选列表
var filtered = itemList.Where("bar==\"value\""); \\all items with bar = value
我想实际检查的是列表中的项是否有一个特定的字符串值,该字符串值不为null或空白。我尝试了以下代码
var filtered = itemList.Where("!String.IsNullOrWhiteSpace(baz)");
它抛出了一个错误
类型为“System.Func`2[DynamicType,System.Object]”的表达式无法运行
用于“Boolean”方法的“System.String”类型的参数
IsNullOrWhiteSpace(System.String)'
虽然我通过以下查询成功地得到了结果
var filtered = itemList.Where("baz!=null && baz!=\"\"");
我想确认是否有一种方法可以在这个查询中使用String.IsNullOrWhiteSpace()
。您可以将“!String.IsNullOrWhiteSpace(baz)”替换为“!(baz==null | | baz.Trim()==String.Empty)”,它应该可以工作。看一看,这里有一个很好的例子
您还需要确保列表
不是列表
,否则System.Linq.Dynamic将无法找到属性
下面是您的示例的一个片段:
void Main()
{
var itemList = new List<dynamic>{ new {foo = true, bar = "a", baz = "b" }, new {foo = true, bar = (string)null, baz = "d" } };
var filtered = itemList.ToAnonymousList().Where("bar != null and bar !=\"\"");
filtered.Dump();
}
public static class EnumerableEx {
public static IList ToAnonymousList(this IEnumerable enumerable)
{
var enumerator = enumerable.GetEnumerator();
if (!enumerator.MoveNext())
throw new Exception("?? No elements??");
var value = enumerator.Current;
var returnList = (IList) typeof (List<>)
.MakeGenericType(value.GetType())
.GetConstructor(Type.EmptyTypes)
.Invoke(null);
returnList.Add(value);
while (enumerator.MoveNext())
returnList.Add(enumerator.Current);
return returnList;
}
}
void Main()
{
var itemList=newlist{new{foo=true,bar=“a”,baz=“b”},new{foo=true,bar=(string)null,baz=“d”};
var filtered=itemList.ToAnonymousList()。其中(“bar!=null和bar!=\”\”);
filtered.Dump();
}
公共静态类EnumerableEx{
公共静态IList到非ymousList(此IEnumerable可枚举)
{
var enumerator=enumerable.GetEnumerator();
如果(!enumerator.MoveNext())
抛出新异常(“无元素”);
var值=枚举数。当前值;
var returnList=(IList)typeof(列表)
.MakeGenericType(value.GetType())
.GetConstructor(类型.EmptyTypes)
.Invoke(空);
返回列表。添加(值);
while(枚举数.MoveNext())
returnList.Add(枚举数.Current);
退货清单;
}
}
我使用您的表达式没有问题-它工作正常
我在EF存储中使用了对象和实体
类型为“System.Func`2[DynamicType,System.Object]”的表达式无法运行
用于“Boolean”方法的“System.String”类型的参数
IsNullOrWhiteSpace(System.String)'
因此,看看这个错误,它是这样表述的(移动订单):
返回布尔值的方法IsNullOrWhiteSpace
,需要类型为System.String
的参数。
但收到的是System.Func``2[DynamicType,System.Object]'类型的表达式
您可能引用了一个对象而不是字符串值来进行比较。但是,如果没有您正在使用的对象的示例代码,以及您是否正在使用对象、实体或LinQ to SQL(我没有尝试过),我们只能猜测您为表达式提供了什么
最后,什么是
“动态项目列表”
您使用的是动态
,还是正常的列表
?您正在更改字符串值,因此只需将字符串设置为变量,而不是硬编码。@jdweng,对不起,我不明白您的意思。我只是想知道为什么String.IsNullOrWhiteSpace()
不起作用我只是键入这个示例来演示一个场景,Trim很好,我想找出的是为什么它与String.IsNullOrWhiteSpace(baz)
有问题,因为if在双引号中。所以你就不能这样做:string myString=“!string.IsNullOrWhiteSpace(baz)”;我的理解是Linq在执行之前会将所有内容转换成SQL。任何在SQL中无法识别的函数都将无法工作。@AndyIZ仅当它是Linq to Entities或Linq to SQL或类似的函数时。Linq to objects与SQL无关,据我所知,作者将动态Linq与普通Linq to objects结合使用。因此,它与动态类型的查询无关,但与你们讨论的翻译相关。我今天发现了这一点,这里OP使用普通LINQ查询,面临着和我一样的问题。但是,是的,他使用的是LINQ to SQL.dynamic,而不是普通的列表