代码改变世界
[登录 · 注册]
  • linq和EF查询的用法和区分
  • 我们做项目时,难免会遇到用的不知道是啥,及把linq和EF搞混了

    今天我带领大家梳理下思路:

    首先说linq查询,然后介绍EF查询

    1.linq查询

    当我们使用linq查询时,转到定义会调到Queryable 类,  那么也就是说,这个类封装了linq所有查询的方法,那么我们来研究研究这个类

    MSDN上是这样解释的:提供一组用于查询实现 IQueryable<T> 的数据结构的 static(在 Visual Basic 中为 Shared)方法。

    命名空间:   System.Linq
    程序集:  System.Core(System.Core.dll 中)

    通过截图可以看出是提供了“IQueryable<T> 的数据结构的 static方法"。

    那么有的人可能并不知道IQueryalbe是干啥的,那么我来解释下:

    IQueryable和IList一样,是用于接收一组数据的集合,
    那么IQueryable和IList有有何区别,看下面
    -------------------------------------------------------------------------------------
    1.IQeurable(IQuerable<T>)不会立即在内存里创建持久数据,只有遍历它(如通过foreach)、把它转换成List等情况下才会向内存加载数据,它可以实现“延期执行”,如果当前被加载的实体有关联实体(associations),此关联实体可被接下来的访问加载。
    2.IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,如果被加载的实体有关联实体(associations),此关联实体不会被加载(既不立即加载,也不延迟加载)。
    看下面一段代码:
    //IList的情况
    IList users = res.ToList(); //此时已把users加载到内存,而每个user的关联实体(UserInfos)未被加载,所以下一行代码无法顺利通过var ss = users.Where(p => p.UserInfos.ID != 3); //此处报错,因为P的UserInfos实体无法被加载
    这提醒了我们有关联实体时,不要使用ToList();
    // IQuerable的情况
    IQueryable users = res.AsQueryable(); //users未被立即加载,关联实体可通过“延迟加载”获得var ss = users.Where(p => p.UserInfos.ID != 3);//此处顺利获得对应的ss
    ---------------------------------------------------------------------------------------------------

    上面提到了IList和IQueryalbe,那么再把这两个方法扩展下,弄清到底是什么东东?
    -------------------------------------------------------------------------------------
    首先看Ilist介绍:
    继承顺序如下:
    Ilist->ICollection ->IEnumerable
    ->Ilist
    为了方便理解,我把知道的都Copy过来好了
    首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口。

    它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,IList<T>可以胜任。

    不过,更多的时候,我们要对集合数据进行处理,从中筛选数据或者排序。这个时候IList<T>就爱莫能助了。

    1、当你只想使用接口的方法时,ILis<>这种方式比较好.他不获取实现这个接口的类的其他方法和字段,有效的节省空间.

    2、IList <>是个接口,定义了一些操作方法这些方法要你自己去实现

    List <>是泛型类,它已经实现了IList <>定义的那些方法

    IList <Class1> IList11 =new List <Class1>();

    List <Class1> List11 =new List <Class1>();

    这两行代码,从操作上来看,实际上都是创建了一个List<Class1>对象的实例,也就是说,他们的操作没有区别。

    只是用于保存这个操作的返回值变量类型不一样而已。

    那么,我们可以这么理解,这两行代码的目的不一样。

    List <Class1> List11 =new List <Class1>();

    是想创建一个List<Class1>,而且需要使用到List<T>的功能,进行相关操作。



    IList <Class1> IList11 =new List <Class1>();

    只是想创建一个基于接口IList<Class1>的对象的实例,只是这个接口是由List<T>实现的。所以它只是希望使用到IList<T>接口规定的功能而已。
    ->Ilist->ICollection->IEnumerable
    ICollection就不介绍了,直接介绍最基础的IEnumerable
    IEnumerable它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代
    IList介绍完毕,接着看IQueryalbe
    转到定义可以看到和IList一样,继承自IEnumerable<T>
    -------------------------------------------------------------------------------------
     Queryable类提供的基本查询方法:Where,Select,,,
    举例:user.Select(u=>u.id).AsQueryable(); db.User.Where().ToList();
    linq查询介绍完毕!

    2.EF查询
    转到定义可以看到,所有EF查询方法都继承自
    DbSet类,那么我们就以这个类说起:
    简要截图:

    
    
    这个类提供了我们最常用的方法 :Add(TEntity entity),Remove(TEntity entity),Find(params object[] keyValues)

    EF查询介绍完毕!

    End:看了上面的介绍,有些人会纠结linq中的select,where和find用法怎么觉得用哪个也行,接下来我来区分下:
    select提供方法如下:
    public static IQueryable<TResult> Select<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector);
    where提供的方法如下:
    public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
    public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int, bool>> predicate);
    find提供的方法如下:
    public virtual TEntity Find(params object[] keyValues);
    根据我实际测试得知:如果有主外键表相关操作时,用EF的find方法,其余能通用的都能通过,
    另外注意上面的返回值类型,linq两个方法返回的都是集合,find返回的是单个实体。但有一点是,它们都可以用var来接收






  • 【推广】 阿里云小站-上云优惠聚集地(新老客户同享)更有每天限时秒杀!
    【推广】 云服务器低至0.95折 1核2G ECS云服务器8.1元/月
    【推广】 阿里云老用户升级四重礼遇享6.5折限时折扣!
  • 原文:https://www.cnblogs.com/shuai7boy/p/5347285.html
Copyright 2008-2020 晋ICP备12007731号-1