接触EF6 不久, 发现.net 的文章明显比java 要少, 分享度比较低。
这里写一下我实践出来的where 用法吧lin49940
db.T.where(
s=>s.oid == 1000 && (s.name.Contains("张三") || s.name.Contains("李四"))
&& (new string[] { "1","2","3"}).Contains(s.type)
&& s.create_date != null && s.updatedate >= 昨天lin49940
&& (s.bz == '字符串比较两种方式一' || s.bz.Equals("字符串比较两种方式二"))
)
生成的sql
select * from T as s
where 1=1
and s.oid = 1000
and (s.name like '%张三%' or s.name like '%李四%')
and s.type in ('1','2','3')
and s.create_date is not null
and s.updatedate >= 昨天lin49940
and (s.bz = '字符串比较两种方式一' or s.bz = '字符串比较两种方式二')
)
上面的查询条件包括了sql 基本的查询运算符
and 和 or, 等于 = , 模糊查询 like, in, 非空 is not null, 空 is null, 不等于 != , 大于 >= , 大于 >, 小于等于<=, 小于<
字符串比较的话, 如果是java 出身的话, 基本会选择Equals() 。
下面讲一下动态拼接查询语句
业务查询的话, 前端很多时候都有多个查询条件,后台要根据前端传递过来的具体查询条件, 组合成一个最终的查询条件。
本来我以为很简单,其他平台都支持的,
query = query.where(查询条件1)
query = query.where(查询条件2)
最终query.toList()
实践过后, 发现没作用的, 太坑爹了,无效, EF6居然只能 query.where(查询条件1 && 查询条件2).toLIst(),怪不得批量删除大家喜欢用EntityFramework.Extensions。
当然这个不是没办法解决的!
拼装sql(当然要预加载,防止sql 注入)是方法之一, 但是这样就跟EF6 不搭边了,EF6的解决的方式, 很多人都是通过 LinqKit 库的 PredicateBuilder(源代码百度就有,直接拷代码就可以使用) 找到了思路lin49940了, System.Linq.Expressions.Expression 其实是能支持拼接查询条件的(lambda 表达式树), 只是EF6 没有提供官方的方法, 自己实现有一点难度, 不过很多人都已经对 PredicateBuilder 进行了封装(我是使用了牟珏玘 的封装版本), 让自己的使用更方便和人性化。
动态拼接查询条件的目标是已经完成, 但是我对System.Linq.Expressions.Expression 和 lambda 表达式想研究一下, lambda 最早接触是通过python 的, 所以理解起来还是不难。
我对于现在的封装版本也是不满意的, 以往的项目, 经过我的封装,我一般都是直接 T.query(map 变量).first()/list()/map()/mapList() , 对所有数据库实体对象都通用,每次查询就是前端封装好一个查询条件的map, 后台一句代码实现, 所以要好好研究一下Expression 和 lambda 表达式树。
s => s.oid = 1000
ParameterExpression Expression.Property Expression.Equal Expression.Constant
参数对象(s) 参数对象的属性(oid) 运算符 = 常量 1000
Expression.Property 是树形的, 可以s.t1.t2.oid, 可以N 多个。
整个lambda 表达式, 其实是可以完整拆分出每个部件的, 每一个查询条件都是Expression, 组合到一个body(也是Expression)里面。
这种body 里面的 lambda 的表达式树, 由 System.Linq.Expressions.Expression