unc
Expression
Expression编译后就会变成delegate,才能运行。比如
Expression
Func
然后你就可以调用func:
func(5) //-返回 true
func(200) //- 返回 false
而表达式是不能直接调用的。
===========================
案例:不正确的查询代码造成的数据库全表查询。
//错误的代码
Func
if (type == 1)
{
predicate = f => f.FeedID == id && f.IsActive == true;
}
else
{
predicate = f => f.FeedID == id;
}
//_questionFeedRepository.Entities的类型为IQueryable
_questionFeedRepository.Entities.Where(predicate);
上面代码逻辑是根据条件动态生成LINQ查询条件,将Func类型的变量作为参数传给Where方法。
实际上Where要求的参数类型是:Expression
解决方法:
不要用Func
//正确的代码
Expression
if (type == 1)
{
predicate = f => f.FeedID == id && f.IsActive == true;
}
else
{
predicate = f => f.FeedID == id;
}
_questionFeedRepository.Entities.Where(predicate);
框架中加入了EF,使开发效率大大加快,但是项目做出来之后,数据稍微多一点,页面的加载速度就会非常慢。经过层层详细的排查之后,发现是项目封装的EF工具类有问题。
///
/// lambda表达式
///
public IQueryable
{
return MyBaseDbContext.Set
}
方法的参数whereLambda,其类型为Func
并且当调用带条件参数的查询方法时,都会遇到这个问题。不过当发现问题之后,基本也就能解决问题了。随后我们发现了与Func
Expression
修改后的方法:
///
/// lambda表达式
///
public IQueryable
{
return MyBaseDbContext.Set
}
修改之后需要注意:
修改为表达式类型后按照之前的思路写可能会报错
LINQ to Entities 不识别方法“System.String ToString()”,因此该方法无法转换为存储表达式。
LINQ to Entities 不识别方法“…get_Item(Int32)”,因此该方法无法转换为存储表达式。
错误原因:
因为底层方法的参数Lambda,由委托类型改为表达式类型。因此咱们写的Lambda表达式里面不能存在C#的方法,比如 ToString()、ToInt()等等。因为表达式类型不能识别。
解决方案:
将Lambda中用到的参数,在外面定义成变量。然后再放到Lambda表达式中。
举例:
//修改之前
listQuestionTypeDetails = this.CurrentDal.LoadItems(u => u.ExamQuestionTypeEntity.QuestionTypeId == enQuestionType.QuestionTypeId.ToString()).ToList();
//修改之后
String questionTypeId = enQuestionType.QuestionTypeId.ToString();
listQuestionTypeDetails = this.CurrentDal.LoadItems(u => u.ExamQuestionTypeEntity.QuestionTypeId == questionTypeId ).ToList();
总结:Expression
Func
Expression
手机扫一扫
移动阅读更方便
你可能感兴趣的文章