首页 > 学院 > 开发设计 > 正文

Linq学习(二)-LinQ to Entity

2019-11-17 03:07:29
字体:
来源:转载
供稿:网友

Linq学习(二)-LinQ to Entity

在昨天我学习了LinQ的一些基础知识和动手写了一些LinQ to Object的例子的基础上,对于LinQ语法和基本的要点有了一定的了解。今天继续自己的学习,对于今天学习的LinQ to DataSet 和LinQ to Entity做自己的一些总结,一方面加深自己的理解,另一方面也能掌握LinQ技术的实现机制,对于也跟我一样对着一方面有兴趣的也可以让大家有个初步的感性认识,也是好的。

今天主要的篇幅会讲解LinQ to Entity的C#实现机制以及解决昨天我看完一小节之后的两点疑惑,后面会花一点篇幅对LinQ to DataSet做一个介绍,那具体的LinQ入门基本上就可以已经介绍完了。

看完了整个章节总结一下LinQ to Entity的实现机制,可以粗略的用下面的图来说明:

EntityFrameWork:是一个对象-关系的映射系统,在关系数据库与c#源代码环境中的对象转换起到了至关重要的作用,没有它的LinQ to Entity估计会找不到对象吧,哈哈哈。它可以将关系数据库中的数据库和数据对象全部映射到LinQ to Entity的上下文环境,分别映射为一个ObjectContext类--数据库对象;和对应的ObjectSet对象---对应的数据库对象(表、视图、存储过程),然后我们通过前面学习的LinQ表达式就可以像操作对象一样访问数据和进行数据操作,其原理就在于关系数据库中的表-行-字段其实都可以映射为对象。这或许就是LinQ to Entity的精髓吧。

结合上面的详解可以更好的理解以下的简略框架分析图,画的有一点丑,能理解就成了:

昨天自己学到这一块存在一个疑问,就是LinQ相对ADO.NET的优势在哪里呢?

在今天的学习中,关于LinQ to Entity的深入学习,了解了它的一些特点,关于其他的LinQ to DataSet/xml/Object来说,都是LinQ内存数据操作的独有的特色,关于LinQ to Entity与ADO.net技术两者差别都都是为了实现数据库访问。以下是我总结的一些区别:

共同点:都是实现数据库访问,LinQ to Entity也没有提供任何不能用ADO.NET实现的特性,就是说两个效果都可以实现,具体用什么技术看使用的场景。

区别:1、更少的代码;LinQ to Entity不涉及数据库底层,不需要编写复杂的SQL语句,通过对象方式进行数据库操作,但最后的数据库更新都是通过SQL语句,也就是Linq 语句其实最终都会解析为SQL语句。

2、LinQ to Entity原理是通过操作缓存数据进行数据操作,最后再统一提交解析sql语句执行更细腻,所以特有的一个特点就是可以批量更新。

3、LinQ to Entity的变更跟踪:提供了系统方法,可以跟踪解析提交的SQL语句。

4、灵活的查询能力;因为不是传统的SQL语句拼接,而是使用LinQ查询模型,可以通过一个模型访问不同的数据库【对于这一个特点,整个章节看完了,也没什么场景例子作证对多个数据库通用一个查询模型的例子,所以可以暂时不用深究】

接下来会通过实际的例子说明通过LinQ to Entity 实现数据库访问:增 、删 、改 、查询(单表查询、关联查询)

【1】首先我们需要生成一个数据模型,它是我们在源代码环境中访问数据库对象的前提:

Entity FrameWork依赖于数据库数据模型来使用LinQ查询,表中的行被转换为行对象的实例,每一个记录的列被转换为行对象的属性。数据库的数据模型可以通过Visual Studio来自动生成,也可以通过新增数据模型文件来手动创建映射,这次的例子采用VS生成,这样简单不太容易出错。

选择【从数据库生成】进入下面:

点击继续:

测试连接通过之后,点击确定,会生成一个连接字符串。以下有个单选项一般默认选择【是】进入下一步:

接下来这个是比较重要的一步:我们可以看到此刻自动添加几个dll引用,同时我们看到它将数据库中的表间关系展现的一览无遗,所以这也是LinQ to Entity的很神奇的地方。

结合上面直观的数据模型图,这里说明一下它的构架:之前系统还原,导致电脑上的Viso没了,所以没能用结构化的图形做下面的说明,大家凑合着理解吧。哈哈

一个数据库的数据模型:(1)派生对象的上下文类:也即是前面说的ObjecgContext,可以理解他就是数据库的一个源代码映射。

(2)实体类:也即是前面我提到的ObjectSet,就是我们刚才所选择映射到程序的表、视图、存储过程的源代码映射。

(2.1)其中实体关系跟SQL中的表关系差不多:有一对一,一对多的关系,其关联通过上面看到的导航属性来关联【表外键】

【2】现在可以试试通过LinQ to Entity访问我们的数据库了。

 //前端显示客户表中的以下字段,今天的例子都是采用系统数据库northWind中的数据  <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">      <Columns>         <asp:BoundField  DataField="id" HeaderText="客户ID"/>         <asp:BoundField  DataField="name" HeaderText="客户姓名"/>         <asp:BoundField  DataField="city" HeaderText="城市"/>         <asp:BoundField  DataField="country" HeaderText="国家"/>      </Columns>    </asp:GridView>

  1. 单表查询:
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Collections;using System.Linq;using System.Data.Objects;//obejctQuery实例的命名空间namespace LinQ{    public partial class _Default : System.Web.UI.Page    {        PRotected void Page_Load(object sender, EventArgs e)        {            //实例化数据库对象ObjectContext            NorthwindEntities myTestDB = new NorthwindEntities();            var retRows = from customer in myTestDB.Customers                          where customer.Country == "USA"                          select new { id = customer.CustomerID,name=customer.ContactName, city = customer.City, country = customer.Country };            GridView1.DataSource = retRows;            GridView1.DataBind();                        //需要将查询的结果转换为ObjectQuery实例,才可以跟踪输出SQL语句            TextBox1.Text = (retRows as ObjectQuery).ToTraceString();        }    }}
View Code

页面显示效果:

转换的SQL语句:

SELECT 1 AS [C1], [Extent1].[CustomerID] AS [CustomerID], [Extent1].[ContactName] AS [ContactName], [Extent1].[City] AS [City], [Extent1].[Country] AS [Country]FROM [dbo].[Customers] AS [Extent1]WHERE N'USA' = [Extent1].[Country]
View Code

2. 关联查询:前端文件也需要修改,这里就不粘贴出来了。直接看一下后端LinQ表达式。

关联查询可以通过两个表达式实现:let 和 selectMany扩展方法实现,本次就let方式做演示。

let方式:

 protected void Page_Load(object sender, EventArgs e)        {            //实例化数据库对象ObjectContext            NorthwindEntities myTestDB = new NorthwindEntities();            var retRows = from customer in myTestDB.Customers                          //let方式实现,不知道是不是为了与SQL中的左外连接一致才采用let作为关键字                          //不过用法很相似                          let leftTab=from order in customer.Orders //这个像不像SQL中的子查询和组过滤表达式,哈哈&hellip;…太像了                                      select order                          where customer.Country == "USA"                          select new { id = customer.CustomerID,name=customer.ContactName, city = customer.City, country = customer.Country,orderCnt=leftTab.Count() };            GridView1.DataSource = retRows;            GridView1.DataBind();                        //需要将查询的结果转换为ObjectQuery实例,才可以跟踪输出SQL语句            TextBox1.Text = (retRows as ObjectQuery).ToTraceString();        }
View Code

转换的SQL语句:

SELECT 1 AS [C1], [Project1].[CustomerID] AS [CustomerID], [Project1].[ContactName] AS [ContactName], [Project1].[City] AS [City], [Project1].[Country] AS [Country], [Project1].[C1] AS [C2]FROM ( SELECT     [Extent1].[CustomerID] AS [CustomerID],     [Extent1].[ContactName] AS [ContactName],     [Extent1].[City] AS [City],     [Extent1].[Country] AS [Country],     (SELECT         COUNT(1) AS [A1]        FROM [dbo].[Orders] AS [Extent2]        WHERE [Extent1].[CustomerID] = [Extent2].[CustomerID]) AS [C1]    FROM [dbo].[Customers] AS [Extent1]    WHERE N'USA' = [Extent1].[Country])  AS [Project1]
View Code

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表