1,Linq简介
全称 Language Integrated Query 即语言集合查询,集成到.net语言中的,即可以使用C#,VB等语言中。支持查询数据源,包括一般的.net对象,如数组,集合,xml,关系数据库
可分为 linq to objects . linq to xml ,linq to datasets, linq to sql 和 linq to entities 技术。
linq实现的内部机制是比较复杂的,然而对于使用它的开发人员来说,使用起来非常方便,一般常使用的是查询表达式,使用它只需要很少的代码就能实现,数据源查询,复杂筛选,排序和分组。
让我们来看看它的语法
from 变量
in 数据源对象
where 条件表达式
orderby 排序列 [ascending][descending]
group 分组条件
into 临时标识符
select 选择列
看,是不是非常类似sql的语法,只是用法类似,机制还是有很大差别的。
【1】 linq to objects 有三种可操作类型,字符串,泛型集合,普通集合。
下面我们来看例子
linq to string
代码:
string name = "zhangsan";
var k= from n in name
where n==‘z‘ 筛选每个char 中有z的
select n; 这里的n代表一个字符
foreach (var item in k)
{
Console.WriteLine(item);
}
结果为z
//linq to List<T>
List<string> lists = new List<string> {
"张三", "李三1", "张三2","李三3"
};
var k = from z in lists
where z.StartsWith("张")//筛选字符串中第一个char有张的。
select z;
foreach (var item in k)
{
Console.WriteLine(item);
}
//结果为张三 张三2,
//linq to ArrayList 与泛型的差不多,有感兴趣的可以去查看具体
但是什么样的对象支持linq查询呢?
一般只要看对象是否实现了IEnumerable<T>接口,如果实现了肯定可以使用。
查询表达式和查询方法
简单对比一个字符串
string name="zhangsan";
查询表达式
from n in name
select n;
查询方法
name.Select(n=>n);这里传的是一个lamda表达式。
很多情况下,查询方法与查询表达式都是混用的,当然查询方法很多,详细的可查看官方文档,这里只是点出使用方法。
【2】linq to entities 实际上就是将DbContext对象包含的各种集合对象作为数据源,这些集合对应的类型为DbSet<T>或ICollection<T>,二者都支持linq操作。linq to entities与 to objects 在查询编码上类似,但在原理上却大不一样。
using(MyDbEntities db=new MyDbEntities()){//前面讲过通过new出数据源上下文
var k=from s in db.users //从数据库获取users表,这里只是获得了一条筛选语句,并没有真正执行,只有在使用到里面的数据的时候才会执行数据库操作,大可不必担心效率问题
where s.name.StartsWith("张")
select s;
}
在实际的 linq to entities查询表达式中,假如数据库中有一列数据为时间类型,如果通过 where s.time>DateTime.Parse("1990-4-4")这样的查询会出现异常,因为牵扯到一个存储区问题,只有使用规范函数才能转换为相应的存储区函数。相应的表,请寻找增加学习能力。
查询多表数据
在 entity frameword中 会根据关系数据库中的主外键关系生成导航属性,导航属性默认定义为virtual属性。
只要关系数据库的关系完整,那么通过查询的数据就可以使多表的。
但如果表之间没有这种关系,就必须使用 join连接查询了
语法
var k= from s in db.users//用户表
join g in db.usertypes//关联用户类型表
on s.typeid equals g.typeid//关联条件
select new {s.name,g.name}//查出用户名字,和用户类型名
关于entity framework中性能优异上的选择,有一种使用变量和不使用变量的不同写法
如 第一种
var k= from s in db.users
where s.name=="张三"
select s;
var kk=k.ToList();
第二种
string name=张三";
var k= from s in db.users
where s.name==name
select s;
var kk=k.ToList();
性能优化
第二种性能要优于第一种,因为底层第二种通过调用存储过程来执行,而第一种每一次使用都要重新编译在执行,而使用存储过程的话只预编译一次。建议使用第二种方式。
context.Configuration.AutoDetectChangesEnabled =false;//该语句用于不启用自动状态跟踪功能
如果启用自动跟踪将会使Add()操作耗费大量性能,会导致DbContext遍历所有缓存的Entry,比较他们的原始值和当前值。
本地数据缓存,指临时文件交换区,把某些数据临时存放在某个地方,用时再取,这样效率更高。
例:
db.users.Count();//这里已经拿到
那么下次再使用 db.users.Local.Count();即可