LINQ和EF区别
EF全名entityframework,它是一个对象关系映射ORM框架。让开发者可以像操作领域对象(domain-specific objects)那样操作关系型数据(relational data)。减少了大部分通常需要编写的数据操作代码。可以使用LINQ来查询数据,使用强类型(strongly typed objects)来检索和操作数据。使开发者可以更加侧重于程序业务逻辑,而非数据访问的基本操作。 LINQ全名为Language Integrated Query,语言级集成查询,里面有封装好的一些方法。
Linq to object
含义:数据源是内存中的集合。它的方法都是在Enumerable(英[ɪ'nju:mərəbəl])类中,都是针对Enumerable进行处理,传递的是委托判断
下面我们实现Linq中的Where方法(yield原理):
public static class LinqExtend { /// <summary> /// 这种写法可以每遍历一次,就把数据展示出来符合的,在调用这个方法的时候是不会真正执行的,
/// Linq中的Where方法就是下面的形式实现的。这是按需获取,这里的是通过语法糖实现的,
/// 只需要IEnumerable+yield,真正编译后也不只是这点代码
/// 会产生很多代码,是一个状态机模式(23种设计模式中的一种) 迭代器 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="func"></param> /// <returns></returns> public static IEnumerable<T> WhereIEnumerable<T>(this IEnumerable<T> list, Func<T, bool> func) { foreach (var item in list) { if (func.Invoke(item)) { yield return item; } } } /// <summary> /// 这种写法会将数据全部遍历整理完成之后才会展示出来, /// 如果有10个符合条件,那就会将10个数据全部放到对象中一次性返回, /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="func"></param> /// <returns></returns> public static List<T> WhereList<T>(this List<T> list, Func<T, bool> func) { List<T> tlist = new List<T>(); foreach (var item in list) { if (func.Invoke(item)) { tlist.Add(item); } } return tlist; } }
下面是调用形式:
var list3 = studentList.JerryWhereIterator(a => a.Age < 30); #region ToList 使用tolist之后,会在JerryWhereIterator内部中遍历出所有符合这个条件的数据输出 var tett = list3.ToList(); #endregion #region foreach则会在JerryWhereIterator中找到一条就返回出来,然后接着遍历找,是一种"按需供给" foreach (var item in list3) { Console.WriteLine(item.Name); } #endregion
之所以会是这种写法,那是因为在WhereIEnumerable方法中的第一个参数中加了this,所以可以将参数studentList提前到方法名的前面,实现上面的这种写法,这是一种语法糖,这样的目的是看起来更方便,有一种陈述式语句的形式,更容易理解。s => s.Age > 30这是通过lambda表达式创建了一个方法作为参数传入了进去。
通过上面分析,我们可以理解到Linq中的Where方法是基于委托的代码封装,把数据筛选的通用逻辑完成,判断逻辑交给委托传递。
Linq to sql
含义:数据源在sqlserver中,所以需要sql语句查询,这个sql语句是从表达式目录树中解析出来的。它的代码也是封装起来的,把数据库操作的固定逻辑封装起来(比如数据库的连接,内部的类型转换之类的),不同的sql就是基于表达式目录树来传递和解读,因为表达式目录树是一种二叉树的数据结构,所以才能解读成sql。
它的方法都是在Queryable类中,比如:
var list = studentList.AsQueryable().Where(s => s.Age > 30);
这里的Where是Queryable类中的:可以看到下面第二个参数和Enumerable类中是不一样的
// // 摘要: // Filters a sequence of values based on a predicate. // // 参数: // source: // An System.Linq.IQueryable`1 to filter. // // predicate: // A function to test each element for a condition. // // 类型参数: // TSource: // The type of the elements of source. // // 返回结果: // An System.Linq.IQueryable`1 that contains elements from the input sequence that // satisfy the condition specified by predicate. // // 异常: // T:System.ArgumentNullException: // source or predicate is null. public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);