最近工作中遇到数据库组合查询带来的一些问题,因此有必要调研一下Linq to Objects Join Linq to Entity。参考一些网友的代码案例,深入实践了一下使用EntityFramework Code First 下的组合查询。

准备环节:

  (一) 在VS下创建一个控制台应用程序(LinqToObjectJoinEntity),定义一个MyObject类,如下:

    public class MyObject
    {  
      public int Identity { get; set; }
      public string Name { get; set; }
      public int Age { get; set; }
    }

  (二)然后再定义一个Entity类及EntityContext类。 

    public class Entity
    {
      public int EntityId { get; set; }
      public string Name { get; set; }
      public string Notes { get; set; }
    }

    public class EntityContext : DbContext
    {
      public IDbSet<Entity> Entitys { get; set; }

      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
        modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();      // 此处是避免使用EF创建出来的Entity表为复数形式,顺便吐槽下微软默认给复数的设计
        modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.OneToManyCascadeDeleteConvention>();   //  此处是避免使用EF创建出的数据库包含数据迁移表

        base.OnModelCreating(modelBuilder);
      }
    }

  (三)使用EF创建准备数据(在Main()函数中实现):

    using (var db = new EntityContext())
    {
      db.Entitys.Add(new Entity { EntityId = 1, Name = "Entity", Notes = "Notes" });
      db.Entitys.Add(new Entity { EntityId = 2, Name = "Frame", Notes = "Mates" });
      db.Entitys.Add(new Entity { EntityId = 3, Name = "Work", Notes = "Honor" });

      db.SaveChanges();
    }

Coding实践:

  (1)重现Linq to Object Join Linq to Entity

    #region Reproduce Linq to Object Join Linq to Entity

    var objectNames = (from myObject in myObjects
             join entity in db.Entitys
             on myObject.Identity equals entity.EntityId
             select myObject.Name).ToList();

    #endregion

    使用Sql Profiler观察到的查询语句如下:

    SELECT
    [Extent1].[EntityId] AS [EntityId],
    [Extent1].[Name] AS [Name],
    [Extent1].[Notes] AS [Notes]
    FROM [dbo].[Entity] AS [Extent1]

    属于全表查询,此乃Linq to objects Join Linq to Entity一大弊害。

  (2)重现 Linq to Entity Join Linq to Object

    #region Reproduce Linq to Entity Join Linq to Object

    var entityName = (from entity in db.Entitys
    join myObject in myObjects
    on entity.EntityId equals myObject.Identity
    select entity.Name).ToList();

    #endregion

    这个地方运行时会抛异常:

      Only Primitive types ('Such as Int32, string, and Guid') are supported in this context

      中文意思是“无法创建类型为“项目名.MyObject”的常量值。此上下文仅支持基元类型(“例如 Int32、String 和 Guid”)"

      看来在涉及这种操作时,我们内存中的数据还不能是非基元类型。List<MyObject> objectList = new List<MyObject>();

      MyObject要为int32, string或者Guid,才能运行通过,并且不是整表查询,而是针对name列的单独查询。

  (3)改进 Linq to Entity Join Linq to Object

    #region Linq to Entity Join Linq to Object(Resolve)

    var identities = myObjects.Select(o => o.Identity);

    var entitytNames = (from entity in db.Entitys
             join identity in identities
             on entity.EntityId equals identity
             select entity.Name).ToList();

    #endregion

    这里Sql Profile监测到的查询语句为:

    SELECT
    [Extent1].[Name] AS [Name]
    FROM [dbo].[Entity] AS [Extent1]
    INNER JOIN (SELECT
    1 AS [C1]
    FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
    UNION ALL
      SELECT
      2 AS [C1]
      FROM ( SELECT 1 AS X ) AS [SingleRowTable2]
    UNION ALL
      SELECT
      3 AS [C1]
      FROM ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2] ON [Extent1].[EntityId] = [UnionAll2].[C1]

    虽是麻烦了些,查出来的东西只有一个。

此文只是针对性的简述下Linq to Object Join Linq to Entity的场景,在日常工作中可能不止于此。

代码见:https://github.com/Jashinck/LinqToObjectJoinEntity

深入调研Linq to Objects Join Linq to Entity的更多相关文章

  1. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  2. LINQ之LINQ to Objects(上)

    LINQ概述 LINQ,语言集成查询(Language Integrated Query),它允许使用C#或VB代码以查询数据库相同的方式来操作不同的数据源. 1.LINQ体系结构 从上图可以看出,L ...

  3. 从LINQ开始之LINQ to Objects(上)

    LINQ概述 LINQ,语言集成查询(Language Integrated Query),它允许使用C#或VB代码以查询数据库相同的方式来操作不同的数据源. LINQ体系结构 从上图可以看出,LIN ...

  4. Linq之旅:Linq入门详解(Linq to Objects)【转】

    http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html Linq之旅:Linq入门详解(Linq to Objects) 示例代码下载:Linq之 ...

  5. Linq之旅:Linq入门详解(Linq to Objects)(转)

    http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html 示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细 ...

  6. Linq之Linq to Objects

    目录 写在前面 系列文章 linq to objects 总结 写在前面 上篇文章介绍了linq的延迟加载特性的相关内容,从这篇文章开始将陆续介绍linq to Objects,linq to xml ...

  7. LINQ to Objects系列(1)相关技术准备

    LINQ to Objects是LINQ的一部分,是查询对象集合的一种语法.首先看一下LINQ的体系结构,这样对LINQ有一个大致的了解.如图. 第一篇文章主要是回顾一下学习LINQ to Objec ...

  8. 编写高质量代码改善C#程序的157个建议[IEnumerable<T>和IQueryable<T>、LINQ避免迭代、LINQ替代迭代]

    前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议29.区别LINQ查询中的IEnumerable<T ...

  9. Linq学习(一)-初涉Linq

    一.何谓LINQ LINQ:Language Integrated Query语言集成查询,其本质是对ADO.NET结果集通过反射连同泛型特性转换成对象集,实现OR模型的转换 二.优点与缺点 优点:封 ...

随机推荐

  1. go语言指南之切片练习

    题目: 实现 Pic.它应当返回一个长度为 dy 的切片,其中每个元素是一个长度为 dx,元素类型为 uint8 的切片.当你运行此程序时,它会将每个整数解释为灰度值(好吧,其实是蓝度值)并显示它所对 ...

  2. GPUImage学习总结

    GPUImage是iOS上一个基于OpenGL进行图像处理的开源框架,内置大量滤镜,架构灵活,可以在其基础上很轻松地实现各种图像处理功能. GPUImgae特性 1,丰富的输入组件 摄像头.图片.视频 ...

  3. 浅析SIEM、态势感知平台、安全运营中心

    近年来SIEM.态势感知平台.安全运营中心等概念炒的火热,有的人认为这都是安全管理产品,这些产品就是一回事,有人认为还是有所区分.那么到底什么是SIEM.什么是态势感知平台.什么是安全运营中心,他们之 ...

  4. GPS同步时钟装置应用及选择

    GPS同步时钟装置应用及选择 GPS是全球定位系统的简称,GPS具有全天时.全天候.高精度.定位和授时服务,GPS卫星授时成本低.安全可靠.覆盖范围广.GPS同步时钟装置,是指从GPS卫星上获取时间信 ...

  5. Python1-变量

    一.变量和简单数据类型 1.变量 命名规则: 变量名组成——字母.下划线.数字(不可做首字符): 用下划线分隔单词,不可包含空格: 关键字和函数名不可做变量名: 小写字母做变量名,不建议使用大小写的字 ...

  6. element UI中的tab切换栏

    html代码:(用的是el-tab组件) <el-tabs v-model="activeIndex" type="border-card" @tab-c ...

  7. 题解 NOI1999【生日蛋糕】—— 洛谷

    自己想出这题的大佬蒟蒻在这儿%您了 我实在是太弱了,搜索这种辣鸡算法都不会(逃 这题真的是想了好久,每次都会T三个点,我以为我的剪枝已经堆了够多了,结果后来才知道是一个关键剪枝没想到OTZ 先贴代码 ...

  8. VS2008文件编码格式修改

    windows下建议使用utf8的编码,vs默认的不是utf8格式,这时需要修改项目文件的模板,在C:\Program Files\Microsoft Visual Studio 9.0\VC\vcp ...

  9. go源码分析(五) 获取函数名和调用者的函数名

    参考资料 实现代码保存在我的github // input flag 1:FunName 2:CallerFunName func GetFuncName(flag int) string {     ...

  10. .tar.xz文件的创建和解压

    创建tar.xz文件:只要先 tar cvf xxx.tar xxx/ 这样创建xxx.tar文件先,然后使用 xz -z xxx.tar 来将 xxx.tar压缩成为 xxx.tar.xz 解压ta ...