Linq学习笔记(2.1)——初识 DLinq

1:创建实体类
   首先为你项表达的数据库数据建立实体类,以后的Demo所用的数据库为Northwind;
    针对产品表(Products)创建产品类

[Table(Name = "Products")]
public class Product
{
    [Column(IsPrimaryKey 
= true)]
    
public int ProductID;
    [Column]
    
public string ProductName;
    [Column]
    
public int CategoryID;
    [Column]
    
public decimal UnitPrice;
    [Column]
    
public bool Discontinued;
}

      为Product类附加Table特性,表示该类对应数据库的Products表,为Product类的属性附加Column特性对应Products表中的列,Column特性有很多属性,如Name,CanBeNull方便你精确表达数据库表的特征,和上例中[Column(IsPrimaryKey=true)]表示用Product的ProductID属性表达数据库表Products的主键。

2:DataContext为你从数据库中取回对象或提交修改的管道,

DataContext db = new DataContext("data source=.\\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Northwind;");
Table
<Product> Products = db.GetTable<Product>();
接着我们使用Linq表达式,从上面查询的Table集合中过滤我们想要的内容。
var Discontinueds = from p in Products
                            where p.Discontinued 
== true
                            select p;
var DiscontinuedsCount 
= Discontinueds.Count();

Response.Write(
string.Format("一共{0}个产品被废弃,他们是:<br>", DiscontinuedsCount));
foreach (var p in Discontinueds)
Response.Write(
string.Format("<div class='showinfo'>price: {1};&nbsp;name: {0}</div>", p.ProductName, p.UnitPrice.ToString()));
上述代码的结果:


推荐定义一个强类型的DataContext取代基本的DataContext类型,然后声明所有的Table集合为Context的成员。
public partial class Northwind : DataContext
{
    
public Northwind(string connection) : base(connection) { }
    
public Table<Product> Products;
    
//public Table<Order> Orders;    
}

Northwind db = new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Northwind;");
Table
<Product> Products = db.Products;

 var Discontinueds 
= from p in Products
                              where p.UnitPrice 
> 50
                              orderby p.UnitPrice
                              select p;
 
foreach (var p in Discontinueds)
 Response.Write(
string.Format("<div class='showinfo'>price: {1};&nbsp;name: {0}</div>", p.ProductName, p.UnitPrice.ToString()));
结果显示:


3:定义关系:
     在关系型数据库中通过主外键来表达各个表之间的关系,Dlinq定义了一个Association特性,你将它附加在你的实体类的某个成员上来表达各个实体间的关系。
using

public partial class _Default : System.Web.UI.Page 
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        Northwind db 
= new Northwind("data source=.\\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Northwind;");
        
var product = (from p in db.Products
                      where p.ProductID 
== 50
                      select p)
                      .First();
          //var product=db.Products.Single(p=>p.ProductID==50);
        var orderCount
=product.OrderDetails.Count;
        Response.Write(
string.Format("产品{0}被订购{1}次,订单ID分别为:<br>", product.ProductName, orderCount));
        
foreach (var o in product.OrderDetails)
            Response.Write(
string.Format("<span class='showinfo'>{0}</span>", o.OrderID));      
    }

}


定义产品实体

定义订单细节实体

构建强类型的DataContext——Northwind
结果显示:

    除了上面直接将关系定义在实体内部外,还有一种简便方法,直接用Linq交叉查询的方法在两个Table集合中联合查询。
var order = from p in db.Products
                    from o 
in db.OrderDetails
                    where p.ProductID 
== 50 && o.ProductID==p.ProductID
            select 
new { p.ProductName,o.OrderID};
Response.Write(
string.Format("产品{0}被订购{1}次,订单ID分别为:<br>", order.First().ProductName, order.Count()));
foreach (var o in order)
    Response.Write(
string.Format("<span class='showinfo'>{0}</span>", o.OrderID)); 
    显示的结果和上面一样。

4:添加,删除,修改实体
    对实体的修改,删除等操作也一样非常简单,你完全可以忘记你现在是在操作数据库!
var product1 = db.Products.Single(p => p.ProductID == 1);
        product1.ProductName 
= "Young's book";

        Product product2 
= new Product { ProductName = "Young's Computer" };
        db.Products.Add(product2);
        db.Products.Remove(product1);
        db.SubmitChanges();
    当然上面的删除和添加操作还需要更健全的实体类,如Product类的ProductID属性,他所附加的Column还需要加上IsDBGenerated = true,因为该列是系统自动产生的自增型整数,在删除product1时,会提示你该实体和OrderDetails有关联,不允许直接删除该product。这些都很简单,稍微摸索摸索就能明白,下次我会作个完整的Demo来完成数据的CURD及多表联合操作!刚刚学完这一部分,感觉比起NHibernate,iBATIS,简单的不止一丁点,像以前学NHibernate,问题一个接一个,网上到处找帖子,发问题,搞了一个多星期才基本上"会用",而用Linq到目前为止完成我用NHibernate的那些功能没有遇到一点阻塞,当然,我现在也刚刚在学,孰是孰非我还不敢乱下评论,有比较熟悉,有兴趣的朋友可以研究比较以下他们的性能!
posted @ 2007-06-08 22:35 Young.Jiang 阅读(5096) 评论(17)  编辑 收藏 网摘 所属分类: Linq

  回复  引用    
#1楼2007-06-09 00:33 | ayu2007[未注册用户]
过来学习的..长见识了.

  回复  引用  查看    
#2楼2007-06-09 09:09 | JerryChou      
现在最新版的vs2005能用的linq哪里下载?
  回复  引用    
#3楼2007-06-09 09:25 | Young
@JerryChou
我现在用的是'Orcas' Express Editions版,只是把webform,window form、c++等程序分开了,但在各自的使用上没有区别
http://msdn.microsoft.com/vstudio/express/future/default.aspx

  回复  引用    
#4楼2007-06-09 10:44 | hasdka[未注册用户]
我的朋友的故事
  回复  引用  查看    
#5楼2007-06-09 11:46 | neuhawk      
比较麻烦的是,vs2005现在不支持.
vs2008可能要到明年.

  回复  引用  查看    
#6楼2007-06-09 12:19 | Phinecos(洞庭散人)      
学习下
  回复  引用  查看    
#7楼[楼主]2007-06-09 13:47 | Young.J      
@hasdka
Who are you?

  回复  引用  查看    
#8楼[楼主]2007-06-09 13:48 | Young.J      
@Phinecos(洞庭散人)
@ayu2007
大家一起学习?如果有什么我理解错误的,多多赐教!

  回复  引用    
#9楼2007-06-09 19:58 | yo136[未注册用户]
学习
  回复  引用  查看    
#10楼2007-06-10 14:37 | 天梦      
使用这样的语句dlinq该怎样解释?


 ArtSb = new StringBuilder();
                ArtSb.Append("SET NOCOUNT ON;");
                ArtSb.Append("UPDATE Article SET Title = @Title, EditTime = @EditTime, TopicId = @TopicId, Hits = @Hits, State = @State,Summary=@Summary,Vip=0 WHERE ID = @ID;");
                ArtSb.Append("SELECT @@IDENTITY AS i");


int i = Data.Database.ExecuteNonQuery(CommandType.Text, ArtSb.ToString(), parms);

上面这个i能得到吗?


  回复  引用  查看    
#11楼2007-06-10 14:45 | 天梦      
@Young.J
不知Young.J试过更新或添加一个没有主键的表没有?
我试过老是报错!

  回复  引用  查看    
#12楼[楼主]2007-06-10 15:32 | Young.J      
@天梦
你的第一个问题的意思应该是得到数据库更新行的IDENTITY值,要知道Dlinq都是面向对象的,你要更新一条数据库的记录就要先找到这条对象对应的实体对象。例如你上面的例子
var id=5;
var as =db.Article.Single(a=>a.id==id);
var identityvalue=as.id
这个就是你想得到的值,当然你还要判断根据最终该实体对象是否更新成功来返回identityvalue的值。
第二个问题,据我了解时不能更新没有主键的表,因为不同的对象在运行时里都有一个唯一的identity,而Dlinq映射得到的实体是通过表的主键来定义该实体的identity的。

  回复  引用  查看    
#13楼2007-06-10 15:59 | 天梦      
@Young.J
谢谢你的回复!
刚才第一个问题说错了,应该是添加的时候,同时得到添加的ID号!?
我现在的用法是先添加字段,再跟据添加的字段得到ID,有没有更好的方法?

  回复  引用  查看    
#14楼2007-06-10 16:13 | 随风流月      
@天梦
可以。
Add 后再访问对象的 ID.

  回复  引用  查看    
#15楼[楼主]2007-06-10 16:18 | Young.J      
@天梦
当然可以返回,还是一样从面向对象的方面考虑,首先设计Article实体类,注意在Article的id字段上加
[Column(IsPrimaryKey = true,IsDBGenerated = true)]
然后添加
Article article = new Article {Title = '11', ……}
这时候你完全不用关心id值,因为你已经标记它为IsDBGenerated,即系统自动产生,然后添加
db.Articles.Add(article );
db.SubmitChanges();
然后你可以用Response.Write(article .id)你会发现该对象的id已经指定赋值了,就是你更新的那条记录的id,注意,article .id只有在SubmitChanges后,即提交更新数据库后才会被赋值

  回复  引用  查看    
#16楼2007-06-10 16:47 | 天梦      
@Young.J
谢谢
解决了我好多天的问题,英文不好,看文档也是看个一知半解!
:(

另一问题:
关于group的问题!
select name,summary from article as a
inner join articleinfo as ai
on a.id=ai.id
group by name,summary

我看了你的group的例子,还不是很了解!能再解释一下上面这句sql 吗?




  回复  引用  查看    
#17楼2007-06-11 14:27 | WOW玩家      
跟nbear类似



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 774363




相关文章:

相关链接:
<2007年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

与我联系

搜索

 

我的标签

个人主页

积分与排名

  • 积分 - 35067
  • 排名 - 1715

最新评论

受教了! (guest)
Select <select_list> FROM <left_table> <join_type> JOIN <right_table> ... (Live & Dream )
@%^&amp;$
?看不懂吗? (Young.Jiang)
莫名其妙!
(%^&$)
创建型验证规则 中 创建了一个 emailAddressValidator ,然后怎样用这个 emailAddressValidator 对象? 接着又创建了一个 shortStringValida... (要有好的心情)