DataContext的讨论 2
我在成都,所以这两天因为地震所以影响一些正常的生活次序.
索引页
DataContext的讨论
一:Identity Tracking
LINQ to SQL 被设计用来解决对象与关系的的不协调,问题在于数据库是关系型的,而语言却是面向对象.我们解决这个问题就是加一个标识,如果我们在多个地方查询数据库,我们期望返回数据存在内存不同的位置.而当我们修改在内存中的记录集的域而不会影响相应的其他域.能这样做就因为数据存储在不同变量中,而变量有不同的地址.
DataContext类给我们提供Identity Tracking.(1)首先在DataContext实例化时记录集就被从数据库中查询出来,(2)使用他的主键记录这个记录集在一个标识表中,实体对象被创建和存储在cache中,接着就是检测标识表是否有相同记录出现.如果已经存在就返回实体对象.
二:Change Tracking
Change Tracking:它是按照存储的一个实体对象的最初值来工作.Change Tracking是一直跟踪到SubmitChanges方法.这时最初值被放弃,并被更改.但在你创建一个个新的实体对象实例,它将不会给跟踪和表识.
http://msdn.microsoft.com/zh-cn/library/bb386982.aspx
三:Change 过程
当你调用SubmitChanges方法时,这个DataContext 对象的change processor管理数据库的更新.首先change processor将插入所有新插入的实体对象到它的 tracked entity objcets list(被跟踪对象列表),接着它将按照外键和唯一性约束的下来更改实体对象.之后,如果没有事务,它将创建一个包含所有SQL命令的事务,提供给SubmitChanges调用.使用SQL Server默认的ReadCommitted的独立级别,提交数据即被读取,锁是共享锁,没有防止数据在事务提交前被更改.最后,枚举出相关的实体数据,生成所需的SQL语句,并执行.如果在枚举出相关的实体数据是有任何错误被触发,SubmitChanges方法就会使用FailOnFirstConfilct.ConflictMode,将这个枚举进程关闭,并且回滚事务,不再更改数据库,如果你将ContinueOnConflict的ConflictMode设置,所有被更改的实体对象将不关任何冲突的被触发继续枚举和处理.同时DataContext会构件一个conflict的列表,但还是要回滚事务,不更改数据库,只不过在这里是更改的实体仍然在,这样就能找出问题再次提交.
四:GetChangeSet方法;
提供对修改对象的跟踪.它返回的是一个只读的IList集合,如果你将你的db.ObjectTrackingEnabled = true;DataContext就会开始跟踪被更改对象,其实在只需要显示数据不需要更改实体,那就不需要使用这 个属性,这样可以提高性能.
五:Submit Changes to the Database
不管多少次更改你的工程,改变的只是替换你的内存中的数据.你没有更改到在数据库中真实的数据.你的改变没有传输到你的服务端,除非你明确调用SubmitChanges方法.
当你明确调用时,DataContext会试着去翻译你的更改,成相同的SQL 命令.你能使用自己定义的逻辑重写这些行为,但需要按照被命名为一个change processor的DataContext的服务的编制次序来做.次序是下面:
(1)当你调用SubmitChanges,LINQ to SQL检验一些列已知对象来决定是否为现有对象追加新实例.如果需要,这些新实例就会被添加到跟踪对象中.
(2)未决定改变的所有对象被放进有依赖关系的有序对象集中被排序.这些对象按照与其他对象的依赖关系来改变.
(3)任何被变化被立即传输前,LINQ to SQL开始一个事务去封装一系列的单独命令.
(4)提交改变的对象的行为被翻译成一句一句的SQL命令并发送到服务端.
要指出,数据库发现任何错误都会引起强制停止进程,并且一个异常会被抛出.如果没有强制停止没有被出发,那数据库的所有改变将会被回滚.在这里DataContext仍然改变完整的记录.因此你能在修改问题后再调用SubmitChanges.
下面是基本的使用
二:几种得到全局唯一DataContext实例的方法:
首先要提到是Rick Strahl的blog,上面有很关于LINQ to SQL的探讨.它有一个案例,可以在这个地址下载,http://www.west-wind.com/files/conferences/conn_LinqToSqlBusiness.zip ,它对现有LINQ to SQL做一写封装(我感觉是没有多大意义),但整个代码比较完整,是很好的学习资料.
在它的blogs上有一个DataContextFactory类,在Web应用程序中使用WebRequest,在Winfrom应用程序中使用Thread,和通常的直接返回DataContext.
DataContextFactory类算是一种制造全局的DataContext的方法.
第二中就是使用HttpContext.Current
在你的DataContext的部分类中添加一个静态方法
这样你就能利用之前在HttpContext中的创建的DataContext的实现,来创建新的实例.
第三中就是可以放在Global.asax文件中关键一个程序级的变量,来存放DataContext的实现,并来创建实例.
这样也是全局的.
也可以利用HttpApplication类来在整个应用程序周期中创建DataContext.
其实有很多方法,主要是看需要,而自己写.
这里有很多讨论.http://www.west-wind.com/WebLog/posts/246222.aspx
索引页
worksguo
www.cnblogs.com/worksguo
索引页
DataContext的讨论
一:Identity Tracking
LINQ to SQL 被设计用来解决对象与关系的的不协调,问题在于数据库是关系型的,而语言却是面向对象.我们解决这个问题就是加一个标识,如果我们在多个地方查询数据库,我们期望返回数据存在内存不同的位置.而当我们修改在内存中的记录集的域而不会影响相应的其他域.能这样做就因为数据存储在不同变量中,而变量有不同的地址.
DataContext类给我们提供Identity Tracking.(1)首先在DataContext实例化时记录集就被从数据库中查询出来,(2)使用他的主键记录这个记录集在一个标识表中,实体对象被创建和存储在cache中,接着就是检测标识表是否有相同记录出现.如果已经存在就返回实体对象.
二:Change Tracking
Change Tracking:它是按照存储的一个实体对象的最初值来工作.Change Tracking是一直跟踪到SubmitChanges方法.这时最初值被放弃,并被更改.但在你创建一个个新的实体对象实例,它将不会给跟踪和表识.
http://msdn.microsoft.com/zh-cn/library/bb386982.aspx
三:Change 过程
当你调用SubmitChanges方法时,这个DataContext 对象的change processor管理数据库的更新.首先change processor将插入所有新插入的实体对象到它的 tracked entity objcets list(被跟踪对象列表),接着它将按照外键和唯一性约束的下来更改实体对象.之后,如果没有事务,它将创建一个包含所有SQL命令的事务,提供给SubmitChanges调用.使用SQL Server默认的ReadCommitted的独立级别,提交数据即被读取,锁是共享锁,没有防止数据在事务提交前被更改.最后,枚举出相关的实体数据,生成所需的SQL语句,并执行.如果在枚举出相关的实体数据是有任何错误被触发,SubmitChanges方法就会使用FailOnFirstConfilct.ConflictMode,将这个枚举进程关闭,并且回滚事务,不再更改数据库,如果你将ContinueOnConflict的ConflictMode设置,所有被更改的实体对象将不关任何冲突的被触发继续枚举和处理.同时DataContext会构件一个conflict的列表,但还是要回滚事务,不更改数据库,只不过在这里是更改的实体仍然在,这样就能找出问题再次提交.
四:GetChangeSet方法;
提供对修改对象的跟踪.它返回的是一个只读的IList集合,如果你将你的db.ObjectTrackingEnabled = true;DataContext就会开始跟踪被更改对象,其实在只需要显示数据不需要更改实体,那就不需要使用这 个属性,这样可以提高性能.
五:Submit Changes to the Database
不管多少次更改你的工程,改变的只是替换你的内存中的数据.你没有更改到在数据库中真实的数据.你的改变没有传输到你的服务端,除非你明确调用SubmitChanges方法.
当你明确调用时,DataContext会试着去翻译你的更改,成相同的SQL 命令.你能使用自己定义的逻辑重写这些行为,但需要按照被命名为一个change processor的DataContext的服务的编制次序来做.次序是下面:
(1)当你调用SubmitChanges,LINQ to SQL检验一些列已知对象来决定是否为现有对象追加新实例.如果需要,这些新实例就会被添加到跟踪对象中.
(2)未决定改变的所有对象被放进有依赖关系的有序对象集中被排序.这些对象按照与其他对象的依赖关系来改变.
(3)任何被变化被立即传输前,LINQ to SQL开始一个事务去封装一系列的单独命令.
(4)提交改变的对象的行为被翻译成一句一句的SQL命令并发送到服务端.
要指出,数据库发现任何错误都会引起强制停止进程,并且一个异常会被抛出.如果没有强制停止没有被出发,那数据库的所有改变将会被回滚.在这里DataContext仍然改变完整的记录.因此你能在修改问题后再调用SubmitChanges.
下面是基本的使用
Northwnd db = new Northwnd(@"c:\northwnd.mdf");
// Make changes here.
try
{
db.SubmitChanges();
}
catch (ChangeConflictException e)
{
Console.WriteLine(e.Message);
// Make some adjustments.
//
// Try again.
db.SubmitChanges();
}
// Make changes here.
try
{
db.SubmitChanges();
}
catch (ChangeConflictException e)
{
Console.WriteLine(e.Message);
// Make some adjustments.
//
// Try again.
db.SubmitChanges();
}
二:几种得到全局唯一DataContext实例的方法:
首先要提到是Rick Strahl的blog,上面有很关于LINQ to SQL的探讨.它有一个案例,可以在这个地址下载,http://www.west-wind.com/files/conferences/conn_LinqToSqlBusiness.zip ,它对现有LINQ to SQL做一写封装(我感觉是没有多大意义),但整个代码比较完整,是很好的学习资料.
在它的blogs上有一个DataContextFactory类,在Web应用程序中使用WebRequest,在Winfrom应用程序中使用Thread,和通常的直接返回DataContext.
DataContextFactory类算是一种制造全局的DataContext的方法.
第二中就是使用HttpContext.Current
在你的DataContext的部分类中添加一个静态方法
public static ADWorksDataContext DataContextInstance
{
get
{
if (HttpContext.Current.Items["ADWorksDataContext"] == null)
HttpContext.Current.Items["ADWorksDataContext"] = new ADWorksDataContext();
return HttpContext.Current.Items["ADWorksDataContext"] as ADWorksDataContext;
}
}
{
get
{
if (HttpContext.Current.Items["ADWorksDataContext"] == null)
HttpContext.Current.Items["ADWorksDataContext"] = new ADWorksDataContext();
return HttpContext.Current.Items["ADWorksDataContext"] as ADWorksDataContext;
}
}
这样你就能利用之前在HttpContext中的创建的DataContext的实现,来创建新的实例.
第三中就是可以放在Global.asax文件中关键一个程序级的变量,来存放DataContext的实现,并来创建实例.
ADWorksDataContext db = new ADWorksDataContext();
Application.Lock();
Application["AllDataContext"] = db;
Application.UnLock();
Application.Lock();
Application["AllDataContext"] = db;
Application.UnLock();
这样也是全局的.
也可以利用HttpApplication类来在整个应用程序周期中创建DataContext.
public class DataContextModule : IHttpModule
{
public void Dispose(HttpApplication context)
{
//dc.SubmitChanges();
dc.Dispose();
dc = null;
context.Context.Items.Remove("$context");
}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
//context.PostReleaseRequestState+=new EventHandler(context_PostReleaseRequestState);
}
//void context_PostReleaseRequestState(object sender, EventArgs e)
//{
//}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Context.Handler is Page)
{
ADWorksDataContext dc = new ADWorksDataContext();
app.Context.Items["$context"] = dc;
}
}
void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Context.Handler is Page)
{
ADWorksDataContext dc = app.Context.Items["$context"] as ADWorksDataContext;
}
}
}
{
public void Dispose(HttpApplication context)
{
//dc.SubmitChanges();
dc.Dispose();
dc = null;
context.Context.Items.Remove("$context");
}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
//context.PostReleaseRequestState+=new EventHandler(context_PostReleaseRequestState);
}
//void context_PostReleaseRequestState(object sender, EventArgs e)
//{
//}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Context.Handler is Page)
{
ADWorksDataContext dc = new ADWorksDataContext();
app.Context.Items["$context"] = dc;
}
}
void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Context.Handler is Page)
{
ADWorksDataContext dc = app.Context.Items["$context"] as ADWorksDataContext;
}
}
}
其实有很多方法,主要是看需要,而自己写.
这里有很多讨论.http://www.west-wind.com/WebLog/posts/246222.aspx
索引页
worksguo
www.cnblogs.com/worksguo