菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
76
0

《深入了解 Linq to SQL》之对象的增删改 —— 麦叔叔呕心呖血之作

原创
05/13 14:22
阅读数 80562

 你的程序里,是否到处充斥着这种代码:

db.Customers.InsertOnSubmit(customer);
db.SubmitChange();

如果某一天,因为 Customers 表的数据库巨增,需要把它拆成两个表,你是否会胆寒???当然,对于查询,我们可以通过视图来解决。对于插入,或者更新呢?据说,现在的数据库在某些情况下,可以对视图进行数据的更新、插入。但是我们要考虑的是不可以的情况。是不是得每个地方都改呀?对于一个大型的项目,这种改动是很可怕的,某个地方少改了,就糟糕了。不过,对于这种情况,Linq to SQL早已经为我们想好了应对的方案。实现 DataContext 继承类中的 InsertCustomer(Customer customer) 方法就可以了,如下图所示。

实现方法的伪代码:

partial void InsertCustomer(Customer instance)
{
        //往表1插入数据
//往表2插入数据
}

当实现了 InsertCustomer 这个方法,Linq to SQL 再往 Customers 这个表插入数据时,将会调用该方法来插入数据,而不是默认的方式。

稍微注意一下,我们发现还有 UpdateCustomer,DeleteCustomer 这两个方法,估计你们也能猜到它们的用途了,没错,就是用来替换掉默认的更新、删除方法。

我们现在接着来考虑一个问题,Linq to SQL 是如何得知 InsertCustomer、UpdateCustomer 和 DeleteCustomer 这几个方法已经实现了呢?通过反射。那我们现在大慨可以得知,Linq to SQL 在插入、更新、删除数据是这么一个过程:

先通过反射,看是否存在 InsertCustomer、UpdateCustomer、DeleteCustomer 这些方法是否存在,如果存在,则调用这些方法,否则采用默认的方法进行增删改。但是,这样会有一个问题,如果插入10条数据,则需要调用反射方法10次,这未免有点笨,众所周知,反射是比较耗性能,而且,这是不必要的性能损失。所以 Linq to SQL 在通过反射把那几个方法找出来后,缓存起来,重复使用。那么,这几个方法是缓存在哪里呢?

在 MetaTable 这个类里面,我们可以看到 InsertMethod、 UpdateMethod 和 DeleteMethod 这三个属性。没错,增删改的扩展方法,就是缓存这里。

我们现在再来理清一下这个流程:

1、在创建 DataContext 的时候,会创建一个影射源(MappingSource)。该影射源会针对每个类,创建一个元表(MetaTable),用来描述表与实体之间的影射。在创建这个元表的时候,通过反射,检查 DataContext 是否有对应实体类的增删改的扩展方法,如果有,则为 InsertMethod、UpdateMethod、DeleteMethod 这三个属性相应地赋值。

2、在插入一条数的时候的时候,先把该实体类对应的元表找出来,看该元表的 Insert 属性是否为空(null),如果为空,则调用默认的插入方法,该方法等价于 DataContext 类中的  ExecuteDynamicInsert 方法。

Linq to SQL 对数据增删改的流程,就是这么个样。

 

 

 

发表评论

0/200
76 点赞
0 评论
收藏