Linq to EF 与Linq to Object 使用心得

MVC+LINQ+EF实战(.NET平台) 学习软件开发的重点是动手实践,只是站在河边学习动作要领和游泳理论,是永远学不会游泳的,你一定要下水试试。这次实例练习主要涉及了三个核心知识,一个是MVC框架,一个是EntityFramework,还有一个就是Linq。     第一步:新建项目,创建一个基于MVC的应用程序,如下图所示:     第二步:在Model层创建edmx文件及其附属类,这里要用到EF。简单来介绍一下EF吧,E 阅读详情

 大家都知道Linq既可以用来查询数据库对象(我这里指的是Entity FrameWork里的Model对象),也可以用来查询内存中的IEnumerable对象。

两者单独查询时都不会出现什么问题,不过混合在一起时(一般是用关键字来join连接),要注意的地方就多着了。


情形1:Linq to Object 连接(join) Linq to Entity

我们首先来看这段代码:(注意:Linq代码里是把内存中的数据代码,也就是Linq to object放在join前面,数据库的数据代码放在join后面)

List<MyObject> objectList = new List<MyObject>();
objectList.Add(new MyObject { Identity = 1, Name = "Jack", Age = 30 });
objectList.Add(new MyObject { Identity = 2, Name = "Sam", Age = 28 });
objectList.Add(new MyObject { Identity = 3, Name = "Lucy", Age = 23 });

EntityRepository repository = new EntityRepository();
DbSet<Entity> entitySet = repository.Context.Set<Entity>();

var objectNames = (from ob in objectList
                   join en in entitySet
                   on ob.Identity equals en.SID
                   select ob.Name).ToList();

Entity是数据库表,有一个bigint型,名为SID字段,其他俩个为Name和Notes。上面的代码中是把Linq to Object放在前面,Linq to Entity 放在join中,编译运行顺利。

实际的查询数据库的语句为:

SELECT 
[Extent1].[SID] AS [SID], 
[Extent1].[Name] AS [Name], 
[Extent1].[Notes] AS [Notes]
FROM [dbo].[Entity] AS [Extent1]
这里是整表查询。(可以打开Sql Server 2008 R2-->Performance Tools-->SQL Server Profiler, 来跟踪此语句)。

如果把以上代码改成select en.Name,仍然是整表查询。

如果是设计两个数据库表的查询,且最后是select 表中的某一列,则不可能是整表查询,而是单独查询了某一列;而这里把entity和object放在一起,就会涉及整表查询。此乃两者混合使用的第一弊端。


情形2: Linq to Entity 连接(join) Linq to Object

数据库的数据代码Linq to Entity在join前,内存中数据代码Linq to Object在join后。代码如下:

 var entityNames = (from en in entitySet
                    join ob in objectList
                    on en.SID equals ob.Identity
                    select en.Name).ToList();
好了,编译通过,运行时抛异常了。

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列的单独查询。大家可以一试。


所以在这里给出大家一点建议:

在涉及到内存中的对象与EF里的对象混合查询时,如果内存中的对象不为基元类型,则先把其中的某个要参加匹配的变量查询出来,再拿着它与EF对象混合查询。

这样不仅不会出错,效率也高,且代码会两段写,也容易看清楚意思。

以上的代码这样,才是最佳的

IEnumerable<long> idList = objectList.Select(o => o.Identity);

var entityNames = (from en in entitySet
                   join id in idList
                   on en.SID equals id
                   select en.Name).ToList();
数据库查询语句如下:
SELECT 
[Extent1].[Name] AS [Name]
FROM  [dbo].[Entity] AS [Extent1]
INNER JOIN  (SELECT 
	[UnionAll1].[C1] AS [C1]
	FROM  (SELECT 
		cast(1 as bigint) AS [C1]
		FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
	UNION ALL
		SELECT 
		cast(2 as bigint) AS [C1]
		FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
UNION ALL
	SELECT 
	cast(3 as bigint) AS [C1]
	FROM  ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2] ON  CAST( [Extent1].[SID] AS bigint) = [UnionAll2].[C1]

虽然里面的操作是麻烦了点,但是最后查询出来的东西却只有Name一个。相对而言,还是比较好的。


情形3:Linq to entities does not recognize the method 'Int32 get_item(int32)'

Linq to entities does not recognize the method 'Int32 get_item(int32)' method, and this method cannot be translated into a store expression

Linq to Entities 不识别方法“Int64 get_Item(Int32)”,因此该方法无法转换为存储表达式。

且看代码

List<long> list = new List<long> { 1, 2, 3 };
var entity = entitySet.Where(en => en.SID == list[1]).ToList();


在这里数组的下标运算放在了linq表达式中,这种情况也是不被允许的。但是用contains,形如list.Contains(en.SID)

或者把下标操作放在linq语句都是可以的。

关系数据库不能识别 含有下标运算的表达式树翻译成的sql查询,为什么会这样呢? 也许要去问微软的工程师吧!

情形4:Only parameterless constructors and initializers are supported in LINQ to Entities

请看如下代码:

 EntityRepository repository = new EntityRepository();
 DbSet<Entity> entitySet = repository.Context.Set<Entity>();
 List<Tuple<long, string>> tuple = entitySet.Select(en => new Tuple<long, string>(en.SID, en.Name)).ToList();

仍然是针对EF的查询。这里的Tuple是元组类,可用多个参数构造成一个元组类(或叫匿名类)。运行时报异常,中文意思为:

LINQ to Entities 仅支持无参数构造函数和初始值设定项。 看来是在linq中使用了带参数的构造函数,linq是不支持这一点的。我们使用匿名类来试试看。

var tuple = entitySet.Select(en => new { en.SID, en.Name }).ToList();

运行正常。但是有些情况下,我们非要使用Tuple来接受这两个参数以便于函数之间的传值,那该怎么办呢? 其实搞清楚真正的原因,自然就有办法了。因为我们在select后

.ToList()时要访问数据库,在这种情况下,带构造函数的Tuple自然是不能苟活的。所以只有在断开数据库后进行此操作才会万无一失。

List<Tuple<long, string>> tuple = entitySet.Select(en => new { en.SID, en.Name })
                                            .AsEnumerable()
                                            .Select(en => new Tuple<long, string>(en.SID, en.Name)).ToList();

entitySet.Select(en => new { en.SID, en.Name })返回的是IQueryable类型,加了个AsEnumerable()之后便是IEnumerable类型,以此来断开数据库连接。

当然,用ToList()或ToArray()亦可!

C# LINQ(一)概况 LINQ前,先回顾下集合:集合基于ICollection、IList、IDictionary、IEnuerable接口及其泛型版本,例如IEnuerable&lt;T&gt;,IList和IDictionary均从ICollection接口派生,而ICollection接口又从IEnumerable接口派生。而泛型版本IEnumerable&lt;T&gt;也派生自IEnumerable,相当于... 阅读详情

相关推荐

Cartographer实现双雷达建图

TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 2 --执行一次前端匹配需要的激光扫描分段数量。关于num_subdivisions_per_laser_scan。num_laser_scans =2,--订阅激光扫描话题数量。Frame改为 前雷达laser_1 后雷达laser_2。雷达的话题由scan改为,前scan_1 后scan_2。有些人说需要改成2,但我这里改成2反而不行,1才可以。

Studying…… 1232

LINQ TO EF的基础操作总结

本文主要是简单地讲述对LINQ TO EF的基本操作,对于数据仓储那些都不进行介绍,有兴趣的可以去了解一下。毕竟“工欲利其事,必先厉其器”嘛。 1. 了解DataContext 想必很多人都用过DataContext来访问数据库吧,这里贴一下DataContext的简单应用实例: namespace 简单的ORM和LINQToSQL示例 { class Program { //定义一个私有的连接字符串 private static readonly

花行远的码园 1187

【安卓逆向】python版本 sha源码

免责声明本文内容仅供学习交流使用,严禁用于商业和非法用途。抓包数据、敏感网址以及数据接口已进行脱敏处理。 注:如有引用,请标注文章地址!!!!!!!

Coodekun的博客 791

第13章 LINQ to Object

第13章 LINQ to Object 在第12章,我们学习了很多C#3的新特性,包括匿名类型、扩展方法、隐式类型等,而这些新特性都是为LNQ服务的。 LINQ to Object将查询语句转换为委托。实际上, LINQ to Object并没有什么全新的东西,它只不过是把之前的语法特性有机地结合了起来,并以我们可以想到的、最易懂、最精简的方式呈现给了开发者。本章将介绍 LINQ to Objec...

yanghuag的博客 818

LinqToObjectLinqToSql的区别

以下不难看出IQueryable继承自IEnumerable 但是二者却有着本质的区别 复制代码 // // 摘要: // 提供针对特定数据源(其中数据类型未未知)评估查询的功能。 // // 类型参数: // T: // 数据源中数据的类型。 public interface IQueryable : IEnumerable, IEnumerable, IQueryable { } 复制代码 这是IQueryable一些实现 包含表达式目录树Expression参数并内置委托 复制代码

weixin_45032957的博客 214

.NET面试题系列[14] - LINQ to SQLIQueryable

.NET面试题系列目录 名言警句 "理解IQueryable的最简单方式就是,把它看作一个查询,在执行的时候,将会生成结果序列。" - Jon Skeet LINQ to ObjectLINQ to SQL有何区别? LINQ to SQL可以将查询表达式转换为SQL语句,然后在数据库中执行。相比LINQ to Object,则是将查询表达式直接转化为Enumer...

anjian4529的博客 284

LINQ to Objects(用于集合、文件、字符串对象的LINQ)

LINQ to  ObjectLINQ的基础,而LINQ to SQL、LINQ to  XML是中间LINQ提供程序,它们主要把数据源转换成LINQ to Objects兼容的类型,以便LINQ to Objects进行操作。LINQ to Objcets就是直接 对IEnumerable或IEnumberable集合使用LINQ查询。LINQ标准查询运算符概述LINQ标准查询运算符是依靠一组扩展方法来实现的。而这些扩展方法分别是System.Linq.Enumerable和System.Linq.Q

游戏全栈,技术合作 3442

【转】Linq to EF Linq to Object 使用心得

大家都知道Linq既可以用来查询数据库对象(我这里指的是Entity FrameWork里的Model对象),也可以用来查询内存中的IEnumerable对象。 两者单独查询时都不会出现什么问题,不过混合在一起时(一般是用关键字来join连接),要注意的地方就多着了。 情形1:Linq to Object 连接(join)Linq to Entity 我们首先来看这段代码:(注意:L...

weixin_34150224的博客 280

EF Core 、LINQ to SQL 、Dapper

EF Core是微软的现代ORM,功能全面,支持多种数据库,适合复杂的数据模型和需要迁移的场景。LINQ to SQL较老,仅支持SQL Server,适合遗留项目。Dapper是轻量级的微ORM,性能高,适合需要直接控制SQL的场景。EF Core开发效率高,但性能可能不如Dapper;Dapper性能好,但需要手写SQL,维护成本可能高;LINQ to SQL已经过时,但维护旧项目可能还需要用到。

weixin_46761444的博客 1774

EF (Entity Framework) vs LINQ to SQL vs SqlSugar 全方位对比分析

本文对比了三种.NET ORM框架:Entity Framework、LINQ to SQL和SqlSugar。EF作为微软官方ORM功能全面但较复杂,适合大型企业应用;LINQ to SQL轻量简单但仅支持SQL Server,适合小型项目;SqlSugar由中国开发者开发,性能优异且支持多数据库,特别适合国内开发场景。三者各具特色,开发者应根据项目规模、数据库需求及团队熟悉度进行选择,其中EF适合复杂业务系统,LINQ to SQL适合简单SQL Server项目,而SqlSugar在性能和易用性方面表

百锦再的博客 1732

LINQ首部曲: LINQ To Object Part 2 - Using VB.NET

 LINQ首部曲: LINQ To Object Part 2 - Using VB.NET 文/黃忠成  續前文,這一篇一樣是發表於Run! PC雜誌,同時收錄於【極意之道-.NET Framework 3.5資料庫開發聖典-ASP.NET篇】一書中,於此我針對VB.NET做了調整。 回到起點: LINQ 語法規則  任何語言皆有其基本語法規則存在,LIN

黄忠成 9871

LINQ to DB 使用教程

LINQ to DB 是一个快速的 LINQ 数据库访问库,它提供了一个简单、轻量、快速且类型安全的层,用于在您的 POCO 对象和数据库之间进行交互。微型 ORM(如 Dapper、Massive 或 PetaPoco)相比,LINQ to DB 在架构上更进一步,您可以使用 LINQ 表达式而不是魔法字符串,同时保持代码和数据库之间的薄抽象层。LINQ to DB 不是像 LINQ to S...

gitblog_00505的博客 797

EFLinq的用法

Linq用法举例1.In操作2.分页3.Like4.Join5.LeftJoin6.UpdateInfoBySql7.QueryDataBySql8.Sub Query9.Group by10.Max11.Min12.Avg13.Count14.Group by 带有Where条件15.多列Group by16.Group by expression17.Any18.Any中带有where条件19.All20.Not Contain21.Group by后,求Min值总结 用法举例 1.In操作 代码如下(

fisea的专栏 2455

EF Linq To Sql 常用查询整理_常用使用方式整理

EF Linq To Sql 常用查询整理_常用使用方式整理 此处案例使用的.net 5.0框架, EntityFrameworkCore的代码,多数使用场景跟.net framework中相同。 使用到的命名空间 using System.Linq; // Linq using System.Collections.Generic; //List using Microsoft.EntityFrameworkCore; // Include() 常用的查询方式整理如下: 一、查询 和 多.

天马3798 2924

EFLinq to Sql、linq的区别

linq是一种查询语言; linq to sql是对数据库设计的ORM(对象映射)方案; EF是一种ORM实体框架,不仅支持sqlserver也支持Oracle等;

qq_35520046的博客 921

C#使用LINQEF Core

LINQ 查询 EF Core 和 LINQ to XML 进行数据操作

qq_42497776的博客 2153

Linq to EF join Linq to object 查询

例子1,2证明 两个连接 位置互换可以查询(限定某些特殊类型:比如List类型)。 例子3,4证明linq to object join Linq to sql select的时候调用本地方法可以查询, Linq to sql join linq to object 调用本地方法不可以查询. 例子1:Linq to sql join linq to object 查询OK,不报错。这是因为List这个类型 List<string> str = new List<strin

weixin_46879188的博客 243

图书管理系统流程图.docx

图书管理系统流程图.docx

上一篇: Linq Max函数与EntityFramework问题
下一篇: c#, enum的初始值0
C云
博客等级 码龄17年 79粉丝 51原创
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值