我不明白为什么这样做。表达对我来说是一个相当新的东西,尤其是在LinqToEntity中使用时。这是我的代码:
var getInt = GetType().GetMethod("getAnInt", BindingFlags.Static |
BindingFlags.NonPublic);
var p = Expression.Parameter(typeof(Student));
var id = Expression.Property(p, "ID");
var eq = Expression.Equal(Expression.Convert(id, typeof(int), getInt),
Expression.Constant(2));
var pred = Expression.Lambda<Func<Student, bool>>(eq, p);
//use the pred in query
foreach(var student in myContext.Students.Where(pred)){
//this always print ID 2 (which equals to the constant above);
//no matter what is returned by the getAnInt method
System.Diagnostics.Debug.Print(student.ID);
}
//the getAnInt method
static int getAnInt(string dummy){
return 100;
}
事实上,我只是在尝试(不是工作中的实际问题)。数据库表中的ID
字段是varchar,其格式为整数(可转换为int)。我正在尝试将id转换为int(但不使用int.Parse静态方法,因为我正在尝试另一种方法),然后再与int常量进行比较。起初我的getAnInt
返回了int.Parse(dummy)
并且工作正常但是
然后我尝试更改它以使其返回任意整数。结果是
令人惊讶的是,无论它返回什么整数,id
似乎都转换为int
确定(好像它被int.Parse
转换)并与Expression.Constant(2)
进行比较,始终过滤ID为2
的学生。
我希望id的转换值应该是getAnInt
的返回值,但它似乎是旁路的。
我还尝试制作另一段代码来测试Expression.Convert
,这表明它可以正常运行:
var t = typeof(Form1).GetMethod("Test", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
var p = Expression.Parameter(typeof(string));
var c = Expression.Convert(p, typeof(int), t);
var e = Expression.Equal(c, Expression.Constant(10));
var f = Expression.Lambda<Func<string,bool>>(e, p);
var k = f.Compile()("1"); //test the value of k to see if it works.
//the parameter will be by-passed
//the return value of Test is obtained
//and compared against constant 10 as expected.
static int Test(string dummy){
return 10; //this makes the k above return true;
//any other value makes it return false;
//It seems to work OK here.
}
这里唯一的区别是第一个代码是在LinqToEntity的上下文中测试的,而第二个代码是直接尝试执行编译的表达式。
我确定我的Students
个实体对我的测试有id
所有感兴趣的值。
如你所见,它只是一个实体集,很简单。我不知道如何调试Expression。第二个测试是我试图确认我是否正确理解Expression.Convert
。
我希望你能在我的第一段代码中发现错误,或者至少给我任何关于可能出错的方向/建议。非常感谢你的帮助。