深入调研Linq to Objects Join Linq to Entity

mac2022-06-30  20

最近工作中遇到数据库组合查询带来的一些问题,因此有必要调研一下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

 

转载于:https://www.cnblogs.com/Jashinck/p/8064076.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)