日期:2014-06-10  浏览次数:20394 次

   昨天由于时间有限,还剩余一些后续,为了保持自己每日总结写博客的习惯,今天来完善昨天的内容,那关于LinQ技术的基础基本上讲完了,剩余的就是看我们在运用中如何将它发挥到极致了。

  •  今日要点:

 

        1LinQ to Entity的并发管理机制

        2LinQ to DataSet的实现

        3EntityDataSource控件

 


 

     1、 首先,我将LinQ to Entity的并发机制画了一个草图,结合昨天博客中说道的它的实现机制,就很容易理解这一点。

其实LinQ to Entity技术可以归结为一句:就是将数据库对象--映射为一个类,而数据库中的每一行数据就是这个类的一个对象,然后全部映射到内存中,采用LinQ表达式,在解析LinQ表达式之后会将操作的对象对应的数据加载到内存,在内存中作为一个临时备份进行预期的数据修改,然后统一提交Entity FrameWork解析为最终的SQL语句,统一执行更新。

但正是这一点导致了它一个致命的缺陷:在你LinQ表达式执行更新前,数据库中该记录由于其他操作比如ADO.NET方式已经发生更新,就导致此时你操作的内存数据已经不是最新的了。而如果提交SaveChange()就会抛出OptimisticConcurrencyException异常。

我们来看一下昨天的一个示例代码:更新一个记录

  //将刚才插入的客户名【无涯子】改为【哈哈哈】
        public void updateData() {

            //实例化数据库对象ObjectContext
            NorthwindEntities myTestDB = new NorthwindEntities();
            Customer data = (from customer in myTestDB.Customers
                            where customer.CustomerID == "george"
                            select customer).Single();
            //操作内存数据
             data.ContactName="哈哈哈";

             //假设以下采用其他方式已经更新了数据库中的ContactName
             updataNameByADOnet(strSQL);//这里是虚拟的一个更新
            try{
            //提交数据更新
             myTestDB.SaveChanges();
}
catch(OptimisticConcurrencyException e){


} }

 

 

 

LinQ to Entity由于只涉及内存资源而无法访问数据库服务器所以无法做到数据对象锁定。但是也提供了一个解决办法,就是为每一个映射到源代码环境的对象字段添加了一个CurrencyMode属性,用于设置是否对该字段校验并发。但是需要一个个 字段的去设置……这无疑是个痛苦的过程。。。。

  为了保持内存数据与数据库数据的一致性,ObjectContent对象提供了一个Refresh()方法,刷新内存数据或更新数据库数据为内存数据。

  还是以刚才的为例,可以在catch体内新增以下两个刷新,最后再提交保存。

            //强制用内存数据刷新数据库,保持一致
             myTestDB.Refresh(RefreshMode.ClientWins, data);

            //数据库数据刷新内存数据,保持一致
             myTestDB.Refresh(RefreshMode.StoreWins, data);

 


 2 接下来简要介绍LinQ to DataSet

   首先来看一下一个结构:

   

 实现DataSet的访问需要实现以下两点:

  •   DataSet没有强类型数据,在LinQ 表达式中需要使用单一字段值时需要调用DataRow.Field<[string][int]>("ColName")扩展方法实现。
  •   DataRow与DataTable仅仅只实现了弱类型的IEnumerable接口,还需要调用AsEnumerable()如:DataTable.AsEnumerable()强制类型转换。

 

3、关于EntityDataSource控件与sqlDataSourcek控件用法没有差别,也提供了一种可视化数据库连接模型。不需要在后端page_load方法中进行LinQ 表达式和数据绑定,前面的功能可以通过以下几个控件来实现。

  •   EntityDataSource:连接数据源

生成页面脚本:

<p>linQ初见篇:学以致用</p>
   
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" DataSourceID="EntityDataSource1">
      <Columns>
         <asp:BoundField  DataField="CustomerID" HeaderText="客户ID"/>
         <asp:BoundField  DataField="ContactName" HeaderText="客户姓名"/>
         <asp:BoundField  DataField="City" HeaderText="城市"/>
         <asp:BoundField  DataField="Country" HeaderText="国家"/>
         
      </Columns>
    </asp:GridView>
  
        <asp:EntityDataSource ID="EntityDataSource1" runat="server" 
        ConnectionString="name=NorthwindEntities" 
        DefaultContainerName="NorthwindEntities" EnableFlattening="False" 
        EntitySetName="Customers" 
        Select="it.[CustomerID], it.[ContactName], it.[City], it.[Country]">
        </asp:EntityDataSource>

 

  页面效果:

   

  • QueryExtender:实现查询、过滤。
    <asp:QueryExtender ID="QueryExtender1" runat="server" TargetControlID="EntityDataSource1">
      <asp:SearchExpression></asp:SearchExpression>
      <asp:RangeExpression></asp:RangeExpression>
      <asp:PropertyExpression></asp:PropertyExpression>
      <asp:OrderByExpression></asp:OrderByExpression>    
    </asp:QueryExtender>