1:创建实体类
首先为你项表达的数据库数据建立实体类,以后的Demo所用的数据库为Northwind;
针对产品表(Products)创建产品类
[Table(Name
=
"
Products
"
)]
public
class
Product
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
[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的主键。
![](https://i-blog.csdnimg.cn/blog_migrate/92f2c8054a3f6cc0dc96a4aff3739e86.gif)
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();
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Response.Write(
string
.Format(
"
一共{0}个产品被废弃,他们是:<br>
"
, DiscontinuedsCount));
foreach
(var p
in
Discontinueds)
Response.Write(
string
.Format(
"
<div class='showinfo'>price: {1}; name: {0}</div>
"
, p.ProductName, p.UnitPrice.ToString()));
上述代码的结果:
推荐定义一个强类型的
DataContext取代基本的DataContext类型,然后声明所有的Table集合为Context的成员。
public
partial
class
Northwind : DataContext
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
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}; name: {0}</div>
"
, p.ProductName, p.UnitPrice.ToString()));
结果显示:
3:定义关系:
在关系型数据库中通过主外键来表达各个表之间的关系,Dlinq定义了一个Association特性,你将它附加在你的实体类的某个成员上来表达各个实体间的关系。
using
#region using
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Linq;
using System.Data.Linq;
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public
partial
class
_Default : System.Web.UI.Page
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
protected void Page_Load(object sender, EventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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));
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
定义产品实体
#region 定义产品实体
[Table(Name = "Products")]
public class Product
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
[Column(IsPrimaryKey = true)]
public int ProductID;
[Column]
public string ProductName;
[Column]
public decimal UnitPrice;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private EntitySet<OrderDetails> _OrderDetails;
[Association(Storage = "_OrderDetails", OtherKey = "ProductID")]
public EntitySet<OrderDetails> OrderDetails
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this._OrderDetails; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ this._OrderDetails.Assign(value); }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
定义订单细节实体
#region 定义订单细节实体
[Table(Name = "Order Details")]
public class OrderDetails
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
[Column(IsPrimaryKey = true)]
public int OrderID;
[Column]
public int ProductID;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private EntityRef<Product> _Product;
[Association(Storage = "_Product", ThisKey = "ProductID")]
public Product Product
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this._Product.Entity; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ this._Product.Entity = value; }
}
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
构建强类型的DataContext——Northwind
#region 构建强类型的DataContext——Northwind
public partial class Northwind : DataContext
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
public Table<Product> Products;
public Table<OrderDetails> OrderDetails;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Northwind(string connection) : base(connection)
{ }
}
#endregion
结果显示:
除了上面直接将关系定义在实体内部外,还有一种简便方法,直接用Linq交叉查询的方法在两个Table集合中联合查询。
var order
=
from p
in
db.Products
from o
in
db.OrderDetails
where p.ProductID
==
50
&&
o.ProductID
==
p.ProductID
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
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
"
;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
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的那些功能没有遇到一点阻塞,当然,我现在也刚刚在学,孰是孰非我还不敢乱下评论,有比较熟悉,有兴趣的朋友可以研究比较以下他们的性能!