SQL ServerLinqToDB 源码分析——前言

LinqToDB介绍


LinqToDB做为三个轻量级的ORM框架。当然能够让开发人士用面向对象的钻探来操作数据库。而且她依照是Linq下边进行支付的。所以一般的Linq操作他也是支撑的。同时小编又扩张对应的DML和DDL。比如增添 Insert,
Delete, Update, CreateTable,
DropTable等措施。相对于EF来讲,LinqToDB显得依旧很弱小,没有那么强劲。LinqToDB能够说只是把Linq动作成为对应的SQL语句。然后在实行操作数据库。那鲜明尤其接近原生态的做法。也是作者为何喜欢的点之一。那么LinqToDB到底能支撑多少种数据库。笔者在Github上也做也明朗提出来。如下。

SQL Server 1

LinqToDB是何许利用啊?笔者在Github上边用了经典的Northwind数据库来讲学。不如小编也来用一下Northwind数据库举办教学本种类的一些试验和列子。Northwind数据库是Sql
Server
3000数据库的经文设计的数据库。假设不懂的情侣,请百度时而。大家都明白EF有三种格局开发。那么是还是不是象征LinqToDB也有大概有那三种开发呢?对于那点小编也没有很明显的表明。LinqToDB并不曾像EF那样子能够依照规划好的类来变化对应的多寡库表结构。只好说脚下LinqToDB有俩种格局来开始展览支付——一种原生态的代码,一种依照TT模板。原生态的代码正是数据库建完事后,配置相应的照射,然后自身工作操作。依照TT模板正是用TT模板生成数据库对象映射。那俩种方法作者会特别的爱抚前一种。

LinqToDB和EF有3个相类似点。他们都有2个重中之重的类。这几个类推动了富有动作的上下文。倘使说DbContext类是EF的中坚,那么DataContext类即是LinqToDB的侧重点。DataContext类的机能跟DbContext类在EF框架之中的功能很类似。使得只有用过EF的人对此LinqToDB有一种亲近感。

 1 using LinqToDB;
 2 using LinqToDB.DataProvider.SqlServer;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 
 8 namespace LinqToDBExample
 9 {
10     public class DbNorthwind:DataContext
11     {
12         public DbNorthwind()
13             : base(SqlServerTools.GetDataProvider(SqlServerVersion.v2008), "Data Source=.;Initial Catalog=Northwind;User ID=sa;Password=123")
14         { 
15 
16         }
17 
18         public ITable<Products> Products { get { return this.GetTable<Products>(); } }
19 
20     }
21 }

作者新建一个类DbNorthwind。让那些类继承DataContext类。同时扩展了收获Northwind数据库中dbo.Products表对应的涉嫌类属性Products。那天特性是多少个ITable接口。当然跟EF的IDbSet接口有一曲同工之妙。是还是不是认为像EF找到了失散多年的小兄弟。而对映射配置上那多少个事情可能看完之后,基本上你会跟作者一样子淡定了诸多。大概你很少用到EF的注释配置,可是那不能够表示他们俩者之间不设有相似之处。

 1 using LinqToDB.Mapping;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 
 7 namespace LinqToDBExample
 8 {
 9     public class Products
10     {
11         [PrimaryKey, Identity]
12         public int ProductID { set; get; }
13 
14         [Column(Name = "ProductName"), NotNull]
15         public string Name { get; set; }
16     }
17 }

看到了吗。能够说没有怎么新的学问。就算没有用过EF,也得以从主要字中取得相应的音信。作者也相信关键字PrimaryKey你在Sql
Server中必将会有用到过。正是主键的情致。那时候来一个简易的询问相应是一件特别棒的事情。能够让大家看出她在询问是怎么着的显示。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace LinqToDBExample
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             using(var db = new DbNorthwind())
13             {
14                 var query = from p in db.Products
15                             where p.ProductID > 25
16                             orderby p.Name descending
17                             select p;
18 
19                 foreach (Products product in query.ToList())
20                 {
21                     Console.WriteLine(string.Format("ProductID:{0} ------------ProductName:{1}", product.ProductID, product.Name));
22                 }
23 
24             }
25 
26             Console.ReadKey();
27         }
28     }
29 }

进行理并了结果:

SQL Server 2

公共场馆,LinqToDB在行使的语法跟EF很接近。正如作者所讲的——如若您真的不太喜欢EF的话,能够试着用一下LinqToDB吧。只怕你能够见到另一片天空也说不自然。

要是你认为下边DataContext类的构造函数用法有一点烦。不担心让作者在介绍一种。平时我们在开发的时候会用到App.config或是Web.config。而对此connectionStrings节点相信大家并不不熟悉。作者要介绍那种正是运用安顿文件来形成。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="linq2db" type="LinqToDB.Configuration.LinqToDBSection, linq2db" requirePermission="false" />
  </configSections>
  <linq2db defaultConfiguration="Aomi" />
  <connectionStrings>
    <add name="Aomi"   connectionString="Data Source=.;Initial Catalog=Northwind;User ID=sa;Password=123" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

LinqToDB本身定义二个配置类。正如上面看到的一规范。我们只要设置上面一段配置就可以了。相信笔者应该能看懂吧。正是内定暗中同意的连年。而对此connectionStrings节点的施用别让小编费神了吗。

<linq2db defaultConfiguration="Aomi" />

安顿好了上边的消息。对应的后续DataContext类的子类就足以不必须去设置相应的连日字符串了。对应的代码如下。

 1 using LinqToDB;
 2 using LinqToDB.DataProvider.SqlServer;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 
 8 namespace LinqToDBExample
 9 {
10     public class DbNorthwind:DataContext
11     {
12         public ITable<Products> Products { get { return this.GetTable<Products>(); } }
13 
14     }
15 }

骨子里那种用配备的格局在EF里面也设有,而地点方法便是通过传播参数来规定相应的连年字符串。只不过上边在配置文件就钦定了暗中认可的总是。所以我们能够绝不钦命暗许的,用直白钦命的点子来取得接二连三。如下

 1 using LinqToDB;
 2 using LinqToDB.DataProvider.SqlServer;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 
 8 namespace LinqToDBExample
 9 {
10     public class DbNorthwind:DataContext
11     {
12         public DbNorthwind()
13             : base("Aomi")
14         { }
15         public ITable<Products> Products { get { return this.GetTable<Products>(); } }
16 
17     }
18 }

设若我们要么不合意的话,作者也只好跪求解脱——因为作者只了然那三种办法了。

开发条件


对此LinqToDB的dll包在NuGet上能够下载到。只要输入“linq2db”即可。同时也足以在Github上边下载(https://github.com/linq2db/linq2db)。最好选用跟我一样子的版本,比较稳定。如下

软件开发工具:Visual Studio 贰零壹壹

LinqToDB版本:linq2db-Release.1.0.7.4

数据库:SQL Server 2008R

LinqToDB的加码效果

对此EF相信咱们都清楚没有何样增添不扩展的定义。至少作者是那样子认为的。因为作者没有看出相应的增多方法。很多个人说难道对二个合伙数据库的集合表进行追加数据就不算扩展吗(那里集合表正是从IDbSet中得来的会晤)。我认不是。EF好像唯有多少有没有爆发变化这些定义。你对集合表操作就显示了多少发现变化。最终交给变化的时候,EF会知道原来扩展了。格局上有一点像是在用DataSet进行数据库。而LinqToDB却不是那样子,他依然有扩张那么些定义了。让小编举一些列子吧。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 
 7 namespace LinqToDBExample
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             using(var db = new DbNorthwind())
14             {
15                 Products product = new Products();
16                 product.Name = "aomi";
17 
18                 db.Insert(product);
19             }
20 
21             Console.ReadKey();
22         }
23     }
24 }

举办结果:

SQL Server 3

地方做了1个粗略的操作。只是可惜LinqToDB的加码效果有一些让小编失望。他并从未像EF那么规范。扩展的时候,要是主键是半自动增添(标识),那么增添成功之后会把主键同步到增添对象中。如图下,扩大成今后大家看出目的ProductID还是0。

SQL Server 4

对于那一点LinqToDB到是用了一种古板的章程。扩张了一叫InsertWithIdentity方法。增添成未来回来对象主键。所以相对于地点想要把扩充成之后的主建同步到对应扩充对象的性质中就必须用古板的格局。小编真的一点受持续。修改如下。

 product.ProductID = Convert.ToInt32(db.InsertWithIdentity(product));

即使下边包车型地铁充实际效果益让小编权且难以接受。可是作者在追加地点还扩张不少措施。让我们得以平素在对应的表属性上面操作。就是ITable接口类型的性质。那一个时候假设设置对象属性值就足以了。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 
 7 namespace LinqToDBExample
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             using(var db = new DbNorthwind())
14             {
15                 db.Products.Value(t => t.Name, "aomi1")
16                     .Insert();
17             }
18 
19             Console.ReadKey();
20         }
21     }
22 }

见到了吗。上边由于笔者的Products类只写了一个天性。ProductID属性又是机动扩大。所以唯有一个Value。若是要对多少个天性设置,就足以在Value在点Value。最后在点Insert或是InsertWithIdentity。

回忆小编进入公司的时候接触的率先个O帕杰罗M框架是Entity
Framework。为了Entity
Framework也看了不些的英文质感(不是小编装B哦)。正式使用八个月后。小编对她有一个周到性的认识。笔者只可以说他着实很有力,也很便利。但是笔者并不是很欣赏他。要问怎么的话,我不得不说喜欢就是喜欢。不爱好正是不爱好。不要求过多的说辞。作者就是那样子的1人。然而作者不会忽略她的无敌的一头。微软的靶子依然老样子——开发不难化。只是在Entity
Framework的数目迁移上边作者不是很喜爱。至少在小编团队开发进度不时会冒出因版本不对导至数据丢失。不管怎么样小编对Entity
Framework的使用也至少有一年的日子。由于项目以世界驱动(DDD)为核情感想。所以在安排的时候,会用到有的作者认为还不易的思辨。比如工作单元(Unit
Of Work形式)。Entity
Framework在初期的时候是不开源码。小编从前是从事JAVA开发的。那对作者来讲心态上有一点不可能接受(当然那也是笔者个人心思)。终于Entity
Framework6开源码了。要是有趣味的意中人能够下载下来看看(源码地址:https://github.com/aspnet/EntityFramework6)。

 结束语


LinqToDB框架有他协调的长处和性格。同样子也有她的阙如。而小编想为大家介绍LinqToDB的施用的同时更想为介绍大家她是怎么着完成的。假如本种类中有出现错误的传教,希望大家能包容。可以的话,请建议来让笔者也学习一下。感谢。

 

LinqToDB的换代作用

看完了LinqToDB的充实际效果益之后。不领悟大家对LinqToDB有没有一种想要去打听冲动呢?没事,让我们看一下LinqToDB周旋异方面,又做了有的什么变化。不,不能够说什么样变动。应该说做了哪些安插。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 
 7 namespace LinqToDBExample
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             using(var db = new DbNorthwind())
14             {
15 
16                 Products product = new Products();
17                 product.ProductID = 79;
18                 product.Name = "aomi update";
19 
20                 db.Update(product);
21             
22             }
23 
24             Console.ReadKey();
25         }
26     }
27 }

地方那段代码做的工作很简短——更新ProductID为79的数目标Name值。执行成功还要更新数据库。你敢信。小编记伏贴场傻眼。过用EF的开发人士都清楚假使大家新建1个平常的目的。注意不是从数据Curry面Linq出来的。而是用new关键字新建的。那时候你打算更新不过EF却会变成扩张。可是LinqToDB却不存在那样子的标题。那设计我给98分。1分是作者不认账——感觉设计思想有好几乱来。早的时候笔者一贯期待见到LinqToDB在操作对象上能像EF或Hibernate那样子——存在对象情形的说法。从扩张的时候主键不能够一起到现在新建对象更新成来看LinqToDB并不曾对象持久化那个说法。也罢,必竟是2个轻量级的O本田UR-VM框架。

地点的革新做法相信大家自然不会有啥样烦感。假使新建的目的设置主键的值之后,都能更新。那么从数据库Linq出来的数额更不用讲了。主尽管要看看一下LinqToDB给大家带来另3个翻新的做法。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 
 7 namespace LinqToDBExample
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             using(var db = new DbNorthwind())
14             {
15                 db.Products
16                     .Where(t => t.ProductID == 83)
17                     .Set(t => t.Name, "Update aomi")
18                     .Update();
19             }
20 
21             Console.ReadKey();
22         }
23     }
24 }

鉴于扩展效益里面包车型大巴Value静态扩展方法出现,导至笔者争执异功能的Set静态扩充方法现身某个也正常。假诺要创新四个性格的值,只即使点八个Set就足以了。当然最后不要遗忘了点Update。更新功用的扩张方法作者依然相比较欣赏的。绝对于EF来讲,EF必须先到数据库得到要更新的对象。然后在改动对象的属性值才能立异。而对此LinqToDB来讲,只要一步到位。

LinqToDB的删减成效

看完了充实和翻新,鲜明不能够忘了看一下LinqToDB在剔除方面是何许做的。正如上边所讲的LinqToDB并从未指标情状这四个说法。所以下边包车型大巴代码删除成功了也不会以为奇怪。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 
 7 namespace LinqToDBExample
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             using(var db = new DbNorthwind())
14             {
15                 Products product = new Products();
16                 product.ProductID = 79;
17 
18                 db.Delete(product);     
19             }
20 
21             Console.ReadKey();
22         }
23     }
24 }

另一种做法:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 
 7 namespace LinqToDBExample
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             using(var db = new DbNorthwind())
14             {
15                 db.Products.Where(t => t.ProductID == 83).Delete();
16             }
17 
18             Console.ReadKey();
19         }
20     }
21 }

地方的俩种做法。作者很淡定的飘过。然则到是印证了1个难点——增加和删除改一般都有俩种办法。一种是从IDataContext接口上扩大出来的不二法门。一种是从IQueryable接口或是ITable接口扩张出来的格局。

在付出八个大型项目标时候,对于多表操作显得见惯司空。所以每一个框架都有温馨处总管务的效果。同样子LinqToDB也落到实处了业务功用。然则他的工作让我很舒畅(Jennifer),不是因为她有多么好。而是她更为切近原生态。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 using LinqToDB.Data;
 7 
 8 namespace LinqToDBExample
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             using(var db = new DbNorthwind())
15             {
16                 using (DataContextTransaction transaction = db.BeginTransaction())
17                 {
18                     try
19                     {
20                         int deleteID = Convert.ToInt32(db.Products.Value(t => t.Name, "aomi79").InsertWithIdentity());
21                         db.Products.Where(t => t.ProductID == 79).Delete();
22                     }
23                     catch (Exception ex)
24                     {
25                     }
26                 }
27             
28             }
29 
30             Console.ReadKey();
31         }
32     }
33 }

地点的做法用的是电动提交业务,假如你想要自身交到的作业的话,一定要设置他的参数。暗许事务是半自动提交业务的。如下,我关闭掉自动提交业务。变成手动提交了。所以传入false。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using LinqToDB;
 6 using LinqToDB.Data;
 7 
 8 namespace LinqToDBExample
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             using(var db = new DbNorthwind())
15             {
16                 using (DataContextTransaction transaction = db.BeginTransaction(false))
17                 {
18                         db.Products.Value(t => t.Name, "aomi83").Insert();
19                         int deleteID = Convert.ToInt32(db.Products.Value(t => t.Name, "aomi79").InsertWithIdentity());
20                         int count = db.Products.Where(t => t.ProductID == deleteID).Delete();
21 
22                         if (count <= 0)
23                         {
24                             transaction.RollbackTransaction();
25                         }
26                         else
27                         {
28                             transaction.CommitTransaction();
29                         }
30                 }
31             
32             }
33 
34             Console.ReadKey();
35         }
36     }
37 }

第叁年时候小编接触了第四个OKugaM框架是LinqToDB。小编不是想强调LinqToDB有多么好。小编只是认为她是三个一定不错的开源O奥迪Q5M框架。成效不比EF差,用法上很接近的EF,却比EF来得轻量,而且又多出了团结的特点。所以一旦你用EF用得有一点烦了大概觉得EF有好几笨重。想去看看有没有其余O奥迪Q5M框架。不烦试试LinqToDB。

相关文章