Linq学习笔记(2.3)——DLinq高级操作

     前面我们学习了使用Dlinq,从面向对象的角度操作数据库的基本一些知识,今天我学习了Dlinq直接执行SQL命令可查询,执行存储过程,事务处理的一些知识,下面是我联系时的一些Demo。
     在这次学习前先向大家将两个Dlinq的知识:
     1:使用工具生成实体。
     前面学习的时候大家可能感觉最麻烦的是根据数据库写映射实体,vs专门提供了工具(C:\Program Files\Microsoft Visual Studio 9.0\SDK\v3.5\Bin\SqlMetal.exe)方便我们自动生成实体,
     SqlMetal /server:.\SQLExpress /database:Northwind /pluralize /namespace:Arcadia /code:d:\Northwind.cs
  大家可以在d:目录下找到Northwind.cs,将其拷贝到您的工程下,下面我们的代码就是在此文件下操作。

     2:显示Linq语句编译后的Sql语句
     方法1:用DataContext的Log属性。db.Log = Response.Output;
     方法2:用GetQueryText / GetChangeText。GetQueryText用于查询时使用,GetChangeText用于更新或删除。
var products = db.Products.Where(p => p.OrderDetails.Count > 50);
Response.Write(db.GetQueryText(products));


ExecuteQuery
    Northwind db = new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;");
    var products 
= db.ExecuteQuery<Product>("select * from Products where ProductID<10");
    products.ToList().ForEach(p 
=> Response.Write(p.ProductName + "<br>"));


ExecuteCommand
   Northwind db = new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;");
    db.ExecuteCommand(
"update [Products] set [ProductName] = {0} where [ProductID]={1}""Young's book"1);

ExecuteCommand用户更新,删除等操作, ExecuteQuery用于查询操作,所以在执行存储过程时要根据情况使用不同的语句。
        Northwind db = new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;");
        var orders 
= db.ExecuteQuery<Order>("exec CustOrdersOrders @CustomerID={0}""ALFKI");
        orders.ToList().ForEach(o 
=> Response.Write(o.OrderID + "<br>"));


Transactions
Northwind db = new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;");

        
if (db.Connection != null) db.Connection.Open();
        db.Transaction 
= db.Connection.BeginTransaction();
        IEnumerator
<OrderDetail> orders = db.OrderDetails.Where(o => o.ProductID == 1).GetEnumerator();        
        
while (orders.MoveNext())
        
{
            OrderDetail od 
= orders.Current;
            od.UnitPrice 
= 200;
        }


        var prod 
= db.Products.Single(p => p.ProductID == 1);
        db.Products.Remove(prod);
        
try{
            db.SubmitChanges();
            db.Transaction.Commit();
        }

        
catch{
            db.Transaction.Rollback();
            
throw;
        }

        
finally{
            db.Transaction 
= null;
        }
    官方的文档介绍Dinq的Transaction这样使用的,不过我有一点不明白,即使不使用Transaction,我测试SubmitChanges()本身就有类似Transaction的功能,如果一系列操作中有一个操作失败,这一系列操作都不会成功,请高手分析一下使用Transaction和直接SubmitChanges()的区别。
     上面这些是用来弥补Dlinq不好用对象处理的复杂数据库操作情景,上面的例子很简单,为了方便理解其使用方法。
posted @ 2007-06-17 19:27 Young.Jiang 阅读(3925) 评论(14) 编辑 收藏

 回复 引用 查看   
#1楼2007-06-17 20:49 | Adrian.      
一个Transaction可以包含多次的SubmitChanges吧, 当发生错误时将回滚之间的所有操作, 当然每次SubmitChanges前的所有行为作为一个元操作也是一个Transaction
 回复 引用 查看   
#2楼[楼主]2007-06-17 21:43 | Young.J      
@Adrian.
谢谢指点,我一会测试一下!

 回复 引用   
#3楼2007-06-18 00:11 | 六天七夜[未注册用户]
Transaction和直接SubmitChanges()的区别太难了
http://www.10089.org.cn/

 回复 引用   
#4楼2007-06-18 11:42 | kindy_wu@msn.com[未注册用户]
请问,DLinq里面如何实现 类似Nhibernate的left join fetch
比如 From Order o Left join fetch o.OrderItems items Left join Fetch items.Product p?
谢谢 !
kindy_wu@msn.com

 回复 引用   
#5楼2007-06-18 12:19 | Young
@kindy_wu@msn.com
我对Nhibernate了解不多,不知道你上面的左链接和SQL的左链接意义是不是一样,如果你看过我前面的文章你就知道如何在有外键链接或无外键关联时查询多个表的数据,你可以用多种联合方式来达到你想要的目的,DLinq同样有join语法。

 回复 引用   
#6楼2007-06-18 14:05 | 上海数据恢复[未注册用户]
计划用三个月时间学号这门课程
不知道行不行
呵呵
给我鼓励吧

 回复 引用   
#7楼2007-06-18 17:00 | kindy_wu@msn.com[未注册用户]
@Young
Left join Fetch可以构造出来一个对象树而不是独立的行。
类似于
Order 和OrderItem是一个一对多的关系,查询出来后,Order的Items属性里面有值。Product也是一样。
有点类似于你前面写过的DataSharp,但是我看到的例子是两个类之间的。
问题1,是能够支持多个类吗?如上例子Order->OrderItem->Product.
问题2,是否有比较简易的语法,因为构造一个DataSharp去关联DataContext感觉比较不舒服。

 回复 引用 查看   
#8楼2007-06-18 19:46 | Melodicsoul      
学习了!
 回复 引用 查看   
#9楼[楼主]2007-06-18 21:21 | Young.J      
@上海数据恢复
3个月时间太久了,应该2个星期,最多1个月,如果学linq要3个月,在学wpf3个月,wcf……,那把3.0-3.5的新东西学完后4.0估计又出来了,我认为一年学习新知识的积累时间应该是2-3个月左右,剩余9-10个月就是把新知识用于工作。

 回复 引用 查看   
#10楼[楼主]2007-06-18 21:33 | Young.J      
@kindy_wu@msn.com
先回答你的第二个问题,手工写实体类的确有点麻烦,就像Nhibernate手工写xml文件和实体类一样,但是我们有工具自动生成实体类,这篇文章开头我已经提过了,你要做的就是好好设计你的数据库和写业务逻辑。下面回答你的第二个问题就是就是在这个自动生成的实体类的基础上操作。
我们查找Order Details表中OrderID=10248,ProductID=11这条订单细节相关联的客户姓名和产品名,这个查询是Orders,Products,Order Details,Customers联合查询的结果。
我们先用一个比较繁琐的方法,假设这些表没有用外键关联。
Northwind db = new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Northwind;");
var order = (from c in db.Customers
from od in db.OrderDetails
from o in db.Orders
from p in db.Products
where o.CustomerID == c.CustomerID &&
od.ProductID == p.ProductID &&
od.OrderID == o.OrderID &&
od.ProductID == 11 &&
od.OrderID == 10248
select new {c.ContactName,p.ProductName }
).First();
Response.Write(string.Format("customername:{0}<br>productname:{1}", order.ContactName, order.ProductName));

第二种方法,如果你的表设计的很周全,用外键关联的很好。这样的查询就方便多了(在提示一下,你只需要设计表,实体有工具来做)。
var order = (from o in db.OrderDetails
where o.OrderID == 10248 && o.ProductID == 11
select new { o.Order.Customer.ContactName, o.Product.ProductName }
).First();
Response.Write(……);
上面两种方法的结果是一样的,因为是基于对象的,配合vs智能感知,可以非常享受整个编程过程:
customername:Paul Henriot
productname:Queso Cabrales

 回复 引用   
#11楼2007-07-23 10:46 | 孤影望月[未注册用户]
请问Linq支持Like查询吗?
而且多View视图是不可修改的吧。。
关于视图的修改,能给个建议吗

 回复 引用 查看   
#12楼2007-09-04 23:05 | 静水≈深流      
学习ing
 回复 引用 查看   
#13楼2007-11-07 10:47 | THIN      
--引用--------------------------------------------------
上海数据恢复: 计划用三个月时间学号这门课程
不知道行不行
呵呵
给我鼓励吧
--------------------------------------------------------
呵呵,你太小看Linq的易用性,我学了两个晚上,一个晚上Dlinq,一个晚上XLinq就拿出去讲课了

同时谢谢博主的资料,比较全,而且例子很好

公告

昵称:Young.Jiang
园龄:5年4个月
粉丝:2
关注:0
<2007年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

搜索

 

个人主页

积分与排名

  • 积分 - 49685
  • 排名 - 2135

最新评论