Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态LINQ-无法在GUID和字符串之间转换_C#_Linq - Fatal编程技术网

C# 动态LINQ-无法在GUID和字符串之间转换

C# 动态LINQ-无法在GUID和字符串之间转换,c#,linq,C#,Linq,我正在动态构建一个LINQ语句。我正在构建的LINQ语句纯粹用于WHERE子句 string[] values = GetPropertyValues(); string propertyName = GetPropertyName(); string clause = string.Empty; if (values.Length > 0) clause = propertyName + "==\"" + values[0] + "\""; 据我所知,我的LINQ查询看起来是正

我正在动态构建一个LINQ语句。我正在构建的LINQ语句纯粹用于WHERE子句

string[] values = GetPropertyValues(); 
string propertyName = GetPropertyName();

string clause = string.Empty;
if (values.Length > 0)
  clause = propertyName + "==\"" + values[0] + "\"";
据我所知,我的LINQ查询看起来是正确的。但当它被执行时,我收到一个错误,上面写着:

运算符“==”与操作数类型“Guid”和“字符串”不兼容

我如何解决这个问题


谢谢大家!

对于一个可为空的值,类似这样的方法可以工作:

clause = "Id.Value.ToString()==\"a\""; /* Id is of type Guid? */
但这显然是一个相当特殊的案例


by Albahari可能是一个更好的解决方案。

听起来GetPropertyName()返回的属性属于Guid类型(我从错误中猜出来),但您试图将其与声明为字符串的值[0]的内容进行比较

动态Linq允许您在where子句中定义参数,以便

string clause = propertyName + "= @1";
LambdaExpression expr = Dynamic.ParseLambda( typeof(YourType), typeof(bool), clause, values[0]);
其中
YourType
是源
IQueryable
中项目的类型。因此,例如,如果源查询是
IQueyable
,那么
YourType
将是
Customer
。无论
propertyName
指示的属性类型是什么,这都将起作用


当它进行解析时,DynamicLinq使用
YourType
propertyName
上的反射来计算lambda表达式的类型参数应该是什么。您得到的lambda表达式应该用作
.Where()
扩展方法的参数。

要与动态linq进行GUID比较,请使用查询属性和提供的示例中的Equals()方法

var items = new[]
            {
                new { Id = Guid.Empty },
                new { Id = Guid.NewGuid() },
                new { Id = Guid.NewGuid() }
            };

var result = items.AsQueryable()
    .Where("Id.Equals(@0)", Guid.Empty)
    .Any();

如果不想将guid作为参数传递,可以将其用于字符串和guid比较:

clause = "Id.Value.Equals(Guid(\"" + values[0] + "\"))";
这就是工作

…或者在您的示例中:

clause = propertyName + ".Value.Equals(\"" + values[0] + "\")";

在没有参数的情况下对我有效

"Id.Equals(Guid(\"D243372F-7ED0-40E6-B93D-6165F7521C29\"))"
“有价值”是行不通的。误差apear

“{类型'Guid'(在索引3处)中不存在属性或字段'Value'。”


请看这里:是否提供值和propertyName的示例数据?GetPropertyName()可能返回一个非字符串对象。所以我猜它应该是字符串propertyName=GetPropertyName().ToString()@Love:我认为它实际上以字符串形式返回属性名(例如,
“Id”
)。这基本上就是构建动态
where
子句(将某个属性的值与不同的值进行比较)所需要的。但是,当动态LINQ编译表达式时,它无法将
Id
(一个
null
)的值与
字符串进行比较。您刚刚保存了我的一天。我现在可以和我的孩子们一起去野餐了:D+1这是正确的答案(尽管值得一提的是,
Where
扩展方法也支持命名参数,所以不需要调用这个静态方法)。OP所做的和这个(我想指出的)之间的实际区别是,本例中的值不必再是字符串;它可以是实际的
Guid
实例。在这种情况下,
GetPropertyValues()
需要返回实际值,而不是它们的字符串表示形式。完全正确。GetPropertyValue的类型必须为object[],而不是string[]。