刚用EF完成了一个十多个表联合、动态条件的查询,因为不熟悉表达式树的使用,就想了笨办法,下面做个总结:
1.EF无法根据条件动态join表,一开始就需要确定使用那些表,准备好数据集;所以把条件分了几个大类,只要条件都属于一个类别的,优先使用这个类别相关部分表的联合查询,能提高效率。如果条件涉及多个类别,就用一个left join所有表的数据集来查询;
2.因为是left join,当数据集中有些字段不是可空字段的时候,查询时会出现类型转换错误,这种情况下,需要在select新字段集时,不可空(null)字段做个处理:NewFieldName=p.FieldName == null ? AA : p.FieldName,这里的AA代表当字段值为空时用来替换的默认值;
3.在给EF的where条件中赋值的时候,如果是在一个foreach的循环中,用var item这个对象来给条件赋值,其结果是,所有条件全部是从最后一个item对象中取值,导致除了最后一个条件赋值正确外,其他全部是错误的。这是应为EF是在最后查询时才生成SQL语句并获取参数并执行的,它的机制中貌似只记录了参数的变量地址,而不是值。解决方法就是,在每次使用item时,定义一个新变量来保存这个对象,即使是在局部范围内定义亦可;部分示例代码:
var qry = from p in Ent.PaInfoes where p.MOBILE != "" select new { p.CNO, p.PNAME, p.GENDER, p.BIRTHDAY, p.MARRIAGE, p.RACE, p.BLOOD, p.PURSUIT, p.MOBILE, p.MAKEDATE, p.MAKEHOSNAME, p.RESPDOCNAME, p.MAKENURNAME, p.JIGUAN, p.COMMUNI }; foreach (var item in pnlConditionList.Controls) { switch (((UCSearch)item).SearchCondition) { //姓名 case SearchCondition.scName: UCSearch usName = (UCSearch)item; if (usName.TextValue != "") qry = qry.Where(d => d.PNAME == usName.TextValue); break;