LINQ入门(完结篇)

来自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=175
GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
http://cnsendnet.taobao.com

到现在为止你还未触碰LINQ,那进来吧 —— LINQ入门(完结篇)
前 言
  各种懒惰,各种拖沓,终究是要动笔写终结篇了,在这个系列的前几篇文章里我们主要学习linq的基础语法以及他对内存数据的操作等,那么本篇文章我们将讨论学习最为大家所熟悉的,也是最受争议的 Linq To SQL,再次强调,如果你到目前为止认为LinqToSql就是linq的话,有以下几种方式可共君选择:1.把这个系列的前面几篇文章给读了。2.到菜市场卖块豆腐给撞了。3.(MM可以忽略跳过哈)把屁股洗干净,让大家把你菊花给爆了。
用 意
  Linq To Sql 相对现在来说,不可否认它已经过时了,伴随着vs2010和Entity Fromwork 4的出现,linq to sql 退出历史舞台是必然的,因为EF4比之更强大更完善。但是linq to sql 并不是一无是处,有很多东西它与EF4是相通的,简单的了解linq to sql并无害处,并且还可以对EF4有一定的过渡帮助。
  由于这个主题能讲的内容非常多,篇幅关系不能全部说完,在这里只能简单地向大家分享个大概,敬请谅解。
目 录
  什么是Linq To Sql
  生成实体
  增删改查
    普通查询
    关联查询
    数据新增
    数据删除
    数据更新
  拓展
  优缺杂谈
  总结
  索引
什么是Linq To Sql
  摘自MSDN:LINQ to SQL 是 .NET Framework 3.5 版的一个组件,提供了用于将关系数据作为对象管理的运行时基础结构。 在 LINQ to SQL 中,关系数据库的数据模型映射到用开发人员所用的编程语言表示的对象模型。 当应用程序运行时,LINQ to SQL 会将对象模型中的语言集成查询转换为 SQL,然后将它们发送到数据库进行执行。当数据库返回结果时,LINQ to SQL 会将它们转换回您可以用您自己的编程语言处理的对象。简单的理解就是我们对数据进行实体化操作,例如我们可以吧每章表作为一个数据实体封装操作。
生成实体
  在linq to sql中,实体对象时一个非常重要的环节,他是对数据表,视图等对象的映射,没有实体就谈不上linq to sql了。也许有些老手会反对为什么是生成实体而不是手写实体,生成实体会产生冗余代码。个人认为对于初学者来说,我们很多手头上的项目通常总是先有库表后有代码,那么我们会针对库表进行编写实体,这真的是个体力活没有任何捷径可言,一张一张表的写实体非常痛苦。所以干脆让大家直接生成,即省事又方便,而且也可以学到怎样编写比较专业的实体。
  既然是生成实体,那么这肯定需要一些而外的工具了,在这里MS自VS2008起就给我们提供了这么一个工具SqlMetal.exe命令工具,可为 LINQ to SQL 组件生成代码和映射。那么接下来我们演示如何生成实体
  1.假设我们有一张用户表,如图:

  2.打开VS2008命令行工具,如图:

3.输入命令,生成数据实体。注意:生成实体文件分别有2种,一种是.cs文件和.xml映射文件的组合方式,另一种则是.dbml文件,只能二选一,切记!!
  首先我们先生成第一种:
.cs和*.xml组合方式,如图:

  4.根据命令指定的位置,我们可以看到对应的生成文件,如图:

 5.将生成的文件放入我们的项目中,如图:

注意,在这里我们要选中“linqToSqlMap.xml”,在属性对话框里设置始终复制到输出目录里,如图:

 6.接下来,我们看看类文件,生成了那些实体代码,如图:

 xml 映射配置文件

从上图看,生成的代码貌似有点多,但是这要比我们自己手写代码更专业。实体文件主要分为两部分,一是数据库上下文关联类 LinqToSqlDemo,二是对应表的实体类 Users 。到这里我们对第一种组合方式的实体生成就已完成。
  接下来我们看看要是我们使用的是生成*.dbml文件又会什么样的场景呢。
  1.同上,输入命令生成文件,如图:

 2.查看生成文件,如图:

3.将生成的DBML文件放入项目里,我们可以看到,生成的只有一个文件,但是当添加到项目里时,项目会自动生成layout和designer两个文件,如图:

 4.有意思东西来了,右键点击dbml文件,选择视图设计器,我们可以在编辑框中得到实体映射编辑视图


5.我们看一下这个时候在.designer.cs文件里生成了哪些内容

可以看到,生成的实体文件和上一种方式生成的实体文件区别不大,由于没有了XML映射配置,所以这里采用的是特性映射配置,在Users实体类中我们可以看到附加了一些如Table,Column的特性标记。
  到此我们对实体生成的做法有了一个基本的认识,接下来我们看看linq 是怎么通过实体进行增删改查的
LinqToSql 增删改查
  1.DataContext 实例
  既然要对数据进行CURD,那么我们就需通过对数据库上下文关联类的实例进行操作之,即DataContext派生类,如上面生成的LinqToSqlDemo派生类。
  由于DataContext 具有多个重载构造函数,在这里针对先前的2种实体生成方式对具体的2个构造函数进行描述,其他的就不逐个介绍少了。详情可以查阅MSDN
  如果使用的是
.cs 与 .xml组合方式的实体映射,那么在构造实例应该如下

如果使用的是
.dbml文件的实体映射,那么就简单了,直接提供数据库连接字符串就可以,因为在派生类的内部已经指定使用特性映射配置。见下图

2.查询数据

// 假设我们已构造了DataContext对象实例dataContext

// 属性log是实例内部的操作日志输出,它属于Stream类型
dataContext.Log = Console.Out;

var users = from usr in dataContext.Users
select usr;

foreach (var usr in users)
{
Console.WriteLine("用户名:{0},Email:{1}", usr.UserName, usr.Email);
}
Console.Read();

  输出结果:

如果我们带上where 条件,查询的操作又是如何的呢

// 假设我们已构造了DataContext对象实例dataContext

// 属性log是实例内部的操作日志输出,它属于Stream类型
dataContext.Log = Console.Out;

var users = from usr in dataContext.Users
where usr.UserName == "张三"
select usr;

foreach (var usr in users)
{
Console.WriteLine("用户名:{0},Email:{1}", usr.UserName, usr.Email);
}
Console.Read();

  输出结果:(这里我们可以看到sql使用了参数化查询)

3.关联查询
  往往在实际项目中我们会涉及到几个表的关联查询,那么LinqToSql有时怎样支持的呢。
  假设多了一张用户详细表,他与用户表的关系如下:

生成实体(.dbml):

在生成的实体代码
.designer.cs文件中我们会看到,Users 实体类多了一个EntityRef<UserDetails> _UserDetails私有字段,而在UserDetails实体类中对了一个EntityRef<Users> _Users私有字段,泛型类EntityRef<T>是关键,他是实体之间关联关系处理主要对象。篇幅关系详情请查阅MSDN点击这里
  查询:

// 假设我们已构造了DataContext对象实例dataContext

// 属性log是实例内部的操作日志输出,它属于Stream类型
dataContext.Log = Console.Out;

var users = from usr in dataContext.Users
select usr;

foreach (var usr in users)
{
Console.WriteLine("用户名:{0},Email:{1},年龄{2},住址:{3}",
  usr.UserName, usr.Email, usr.UserDetails.Age, usr.UserDetails.Address);
}
Console.Read();

  输出结果:

从结果我们可以看到,首先是把用户表给查了,然后根据linq延迟加载的特性,只有真正使用时才执行,因此当需要查看用户详细信息时才会去执行用户详细查询,这样就带来了很大弊端,如果数据量大时那么这样的查询开销就大了,大大降低了程序的效率。那么这个问题是否可以解决呢?答案是肯定的,请看下面代码:

// DataLoadOption数据导入操作对象,它可以告诉linq在执行查询是否延迟
// 查询对象的子对象
var loadOption = new DataLoadOptions();
// 设置数据导入对象关联关系
loadOption.LoadWith<Users>(usr => usr.UserDetails);

dataContext.LoadOptions = loadOption;

var users = from usr in dataContext.Usersselect usr;

foreach (var usr in users)
{
Console.WriteLine("用户名:{0},Email:{1},年龄:{2},住址:{3}",
usr.UserName, usr.Email, usr.UserDetails.Age, usr.UserDetails.Address);
}
Console.Read();

  输出结果:

从log我们可以看到这样就是一条语句查出来数据结果集。注意,这里演示的是2表关系的查询,如果当我们再多出一个表,而这表是与用户详细表形成关联关系的时候那么,DataLoadoption 就没法解决了一次性查出,而又回到类似上一个样例分次查出来。例如:
  假设新增一张表(UserDetails2):
  关系如下:

 生成*.dbml:

查询:

// 假设我们已构造了DataContext对象实例dataContext

// 属性log是实例内部的操作日志输出,它属于Stream类型
dataContext.Log = Console.Out;
// DataLoadOption数据导入操作对象,它可以告诉linq在执行查询是否延迟
// 查询对象的子对象
var loadOption = new DataLoadOptions();
// 设置数据导入对象关联关系
loadOption.LoadWith<Users>(usr => usr.UserDetails);
// 加入对表UserDetails2的关联
loadOption.LoadWith<UserDetails>(dtl => dtl.UserDetails2);

dataContext.LoadOptions = loadOption;

var users = from usr in dataContext.Users
select usr;

foreach (var usr in users)
{
Console.Write("用户名:{0},Email:{1},年龄:{2},住址:{3}",
  usr.UserName, usr.Email, usr.UserDetails.Age, usr.UserDetails.Address);
foreach (var dtl in usr.UserDetails.UserDetails2)
{
Console.Write(",性别:{0}", dtl.Sex);
}
Console.Write("\r\n");

}
Console.Read();

  查询结果:

来自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=175
GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
http://cnsendnet.taobao.com

原文地址:https://blog.51cto.com/14036626/2460468

时间: 2024-10-07 05:45:24

LINQ入门(完结篇)的相关文章

新注册第一帖----------------------乱码新手自学.net 之Linq 入门篇

作为一个业余开发,断断续续学.net/c#也有不少日子了, 学习过程中,不断忘了学,学了忘,这让我很苦恼. 以前学习过程中,我总是在笔记本中记录下来知识要点,这么久下来,笔记本都写了四五本了. 然而,随着笔记本的增多,自己很快发现,笔记写了跟没写一样:笔记多了就找不到了-- 所以,我觉得还是上博客园写博客,记录自己每天的学习心得. 如果有什么错误的地方,欢迎大神指教,小弟在这给大神跪谢了 ======================================================

怒学Python——完结篇——I/O

好吧,没想到居然这么快,才两天我就把入门看完了,当然只是入门,以后如果用到,会把那些各个类型的细化都总结一下例如数学函数,或者总结一下一些框架的应用如Scarpy(爬虫框架,听着就很兴奋呢,很多人都是了解有,但是没用过......),笔者写完这段暂时先开心的看电影去,回学校再说. Python的屏幕I/O:如果是交互式编程,直接输入就好,这里的是在脚本式编程才用到,用到的方法是input和raw_input,下面给出例子 #!/usr/bin/python print raw_input() #

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

示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集成查询).通过LINQ,我们可以使用相同API操作不同的数据源.接下来就让我们看看LINQ是什么以及如何使用? 再此之前,需要先了解的相关技术 1. 隐式类型.匿名类型.对象初始化器 1) 隐式类型,使用var关键字创建,C#编译器会根据用于初始化局部变量的初始值推断出变量的数据类型.(不过我个人认

ASP.NET 5系列教程(七)完结篇-解读代码

在本文中,我们将一起查看TodoController 类代码. [Route] 属性定义了Controller的URL 模板: [Route("api/[controller]")] 所有符合该模板类型的HTTP 请求都会被路由到该controller.在本例中, 路由的命名规范为对应Controller 的前缀,对于TodoController 类,路由模板为 “api/todo”. HTTP 方法 [HttpGet].[HttpPost]和[HttpDelete] 属性定义为 co

ASP.NET MVC学习---(九)权限过滤机制(完结篇)

相信对权限过滤大家伙都不陌生 用户要访问一个页面时 先对其权限进行判断并进行相应的处理动作 在webform中 最直接也是最原始的办法就是 在page_load事件中所有代码之前 先执行一个权限判断的方法 至于其专业的权限机制这里不做讨论 想要了解的同学可以自行google之 或者点击进入: webform专业的权限验证机制 那么mvc中是如何实现权限验证的? 据我们所知 mvc中是根据路由配置来请求控制器类中的一个方法 并没有webform中的page_load方法 难道我们要在每个actio

Java工程师学习指南(完结篇)

Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校生,所以写的内容主要还是针对Java初学者或者接触Java后端不久的朋友,不适用于已经工作多年的Java大佬们.所以本文中的方法不一定适合所有人,如有错误还请谅解. 本期的内容是系列文章的最后一部分内容了.这个系列可能还有很多东西没有说清楚,也有很多内容被忽略了.但是这些内容也确实是笔者结合自己经验

LINQ入门(中篇)

来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=163GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com 到现在为止你还未触碰LINQ,那进来吧 —— LINQ入门(中篇) 前言 在上篇中简单的分享了LINQ的基础概念及基础语法,如果没有阅读过上篇的朋友可以点击这里.感谢大家的支持,本篇我们将更进一步的学习LINQ的一些相关特性及应用方法.废话不多说,请往下阅读吧. 延迟加载 在上篇中

LINQ入门(下篇)

来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=172GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com 到现在为止你还未触碰LINQ,那进来吧 —— LINQ入门(下篇) 前言 终于来到下篇了,通过上篇,和中篇,我们了解了linq的基本语句,对应linq我们又了解到lambda表达式,静态扩展方法,以及linq的延迟加载的特性,那么在本篇文章中我们将分享学习一下linq对于我们开发中

Asp.net之LINQ入门视频教程

当前位置: 主页 > 编程开发 > Asp.net视频教程 > Asp.net之LINQ入门视频教程 > http://www.xin1234.com/Program/AspnetShiPin/AspNetLINQYmSp/ 1.掌握LINQ中的基本概念 上传日期:2014-09-17 02:57:38 相关摘要: - LINQ有关的语言特性:隐式类型 - 网络不稳定的基本处理方法 - python的编程概念比较全面,比vba来得全面,适用范围也广得多了 2.理解扩展方法Lambd