类似以下代码:
IQUERYABLE<T> GetSomething(bool flag1,bool flag2)
{
//因为要进行一些必要的操作,所以不可以直接
Iqueryable<T> list =_dbcontext.T.Where(..条件1..);
if (flag1==true)
{
//这句是错误的
list=list.where(..条件2..);
//这样才可以
list=_dbcontext.T.where(....条件1+条件2....)
}
if (flag2==true)
{
.......
}
......后面的代码略..............
}
问题在于:我的本意是按照红色代码的形式根据传入的参数flag进一步筛选,可是提示错误,有什么解决方法呢?
11日12点
已经确认条件2涉及导航属性导致的问题,之前有看过一个贴子,找不到了现在,汗的。。。
------------------------------------------------------------------------------------------
谢谢大家先:)
To gunsmoke:
有这样想过,不过感觉这样可读性差一些,每个条件可能是若干个判断的。
To dudu, Joe Hou:
错误:未将对象引用设置到对象的实例
To Zigzag:
条件2中有访问到外键字段的
刚才试一下,如果条件2用到导航属性就会出错,这个怎么解决?
----------------------------------------------------------------------------------------
14日
----------------------------------------------------------------------------------------
我不知道我犯的这个错大不大:)这个还请指教一下,谢谢谢谢先!
Model部分类里边,没有定义外键。
之前是这样:
public class TMetaData
{
...........
//刚刚加上去的
[ForeignKey("A")]
//之前只有这个
public int aid{get;set;}
//刚刚加上去的
public virtual A A{get;set;}
...........
}
然后在repository里
IQueryable<T> list=_dbcontext.T.include("A").where(...非导航属性条件...)
list=list.where(...导航属性A的筛选...)
这样是可以的。暂时先这样用着,不过我感觉dudu指的构建表达式树确是王道,过后再学习吧。
这样应该是可以的,具体出现的是什么错误?
谢谢,烦请看一下问题补充。
@BorgChen: 我想到了一个解决方法,正在写代码
@BorgChen: 提供一个思路吧,需要写一堆代码。
“条件1”与“条件2”分别是两个System.Linq.Expressions.Expression<Func<T, bool>>。
if (flag1==true) 合并这两个表达式。。。
@dudu: 你的意思是先组合条件最后再取数据是不?
是个好办法,不过Expression真真没用过,超出知识范围了已经。
@BorgChen:
根据条件组合Where中的表达式
Where方法的参数就是Expression
上MSDN看Expression的示例,晕晕的。。。。
另外在园子里搜到这个随笔,好像是用来处理这个的,但是也真是不明白用法。
MVC+LINQToSQL的Repository模式之(四)数据统一更新的附加类
http://www.cnblogs.com/lori/archive/2011/11/07/2240456.html
@BorgChen: 试试园子里这篇文章中的方法:LINQ动态组合查询
@dudu: 这个写起来方便了一些,还有有遗憾的地方,如果是实体本身的字段,这个可以,但是对于导航属性的字段,目前还是没有调试出来。
谢谢dudu,以及楼上楼下的大家伙儿,一点分数整了大家几天,真是对不住!
@dudu:
我不知道我犯的这个错大不大:)这个还请指教一下,谢谢谢谢先!
Model部分类里边,没有定义外键。
之前是这样:
public class TMetaData
{
...........
//刚刚加上去的
[ForeignKey("A")]
//之前只有这个
public int aid{get;set;}
//刚刚加上去的
public virtual A A{get;set;}
...........
}
然后在repository里
IQueryable<T> list=_dbcontext.T.include("A").where(...非导航属性条件...)
list=list.where(...导航属性A的筛选...)
这样是可以的。暂时先这样用着,不过我感觉dudu指的构建表达式树确是王道,过后再学习吧。
@dudu:
不过好像初始化的时候性能有点问题,但是再次点击的时候又不会
@BorgChen: EF初始化时开销本来就大
试试这样
IQueryable<T> list = _dbcontext.T.Where( 条件1 && ( flag1 == false || 条件2) && ( flag2 == false || 条件3) )
谢谢,烦请看一下问题补充。
如果数据不是太多的话,建议直接加载到内存中试试,list = list.Where()这句如果是延迟加载的话,有可能是有问题。把Iqueryable<T> list =_dbcontext.T.Where(..条件1..);换成如下语句试试:
IList list =_dbcontext.T.Where().ToList();
@Zigzag: 请问是不带实体的IList?
@Zigzag: tolist照样提示错误。
问题在你的条件2里写的到底是什么,是不是访问了其他数据,如果只是简单的条件,应该是可以的。
谢谢,烦请看一下问题补充。
刚刚又看了一下,试着把出错的行,改了一下条件,不涉及外键,就可以。
但问题是,肯定要用到导航属性的,再次问一下有什么方法可以解决。
@BorgChen: 这个需要看代码,要看你是不是延迟加载。EF有一些陷阱需要注意。最保险的办法就是通过ToList()方法加载到内存中,在使用linq语句,基本不会出错。
IList<T> list=_dbcontext.T.Where(...1...).toList() 之后,
if
list=list.where(...2...).toList()
仍然报一模一样的错误
比较高深,看不太明白。
上错误信息哈
谢谢,烦请看一下问题补充。
@BorgChen: 这个error太笼统了。。。水平有限,猜不出来,等高人。
或者贴完整代码,免费帮调试。。。