不得不再次给关注dlinq的朋友道歉了。好久都没有更新blog了。因为工作的变动,还要赶期限,没有时间关注这里了。
先发布一则消息。Orcas Beta1, 这个才是beta1,可以到http://www.microsoft.com/downloads/details.aspx?FamilyID=f10fb5df-e369-4db4-b9a7-845dbf793368&DisplayLang=en 下载。5月1号的版本。最早4月19号就出来过一个,只是没有在意。还有一个http://www.microsoft.com/downloads/details.aspx?FamilyID=36b6609e-6f3d-40f4-8c7d-ad111679d8dc&DisplayLang=en 。 一个是self-extracting 版本的,一个是Virtual PC version的。不知道什么区别。没有装过。
本节舍去原来的计划,而改讲映射工具。在入门三一文中,我们提到了sqlmetal这个工具。http://www.cnblogs.com/126/archive/2006/09/06/492332.html sqlmetal的功能是将数据库的信息抽提出来,生成映射代码。Orcas还有另外一个工具,就是O/R Designer.
先讲sqlmetal. 自上次的版本后,sqlmetal,又增加了一些新的功能。比如,支持SQLCE版本的Sql Server, 支持直接输入connection string, 等等。 这是sqlmetal的帮助信息,是不是比上次多了很多?
<
input
file
>
]
Generates code and mapping for the LINQ to SQL component of the .NET framework. SqlMetal can:
- Generate source code and mapping attributes or a mapping file from a database.
- Generate an intermediate dbml file for customization from the database.
- Generate code and mapping attributes or mapping file from a dbml file.
Options:
/server:
<
name
>
Database server name.
/database:
<
name
>
Database catalog on server.
/user:
<
name
>
Login user ID (default: use Windows Authentication).
/password:
<
password
>
Login password (default: use Windows Authentication).
/conn:
<
connection
string
>
Database connection string. Cannot be used with /server, /database, /us
er or /password options.
/timeout:
<
seconds
>
Timeout value to use when SqlMetal accesses the database (default: 0 wh
ich means infinite).
/views Extract database views.
/functions Extract database functions.
/sprocs Extract stored procedures.
/dbml[:file] Output as dbml. Cannot be used with /map option.
/code[:file] Output as source code. Cannot be used with /dbml option.
/map[:file] Generate mapping file, not attributes. Cannot be used with /dbml option
.
/language:
<
language
>
Language for source code: VB or C# (default: derived from extension on code file name).
/namespace:
<
name
>
Namespace of generated code (default: no namespace).
/context:
<
type
>
Name of data context class (default: derived from database name).
/entitybase:
<
type
>
Base class of entity classes in the generated code (default: entities have no base class).
/pluralize Automatically pluralize or singularize class and member names using English language rules.
/serialization:
<
option
>
Generate serializable classes: None or Unidirectional (default: None).
/provider:
<
type
>
Provider type (default: provider is determined at run time).
<
input
file
>
May be a SqlExpress mdf file, a SqlCE sdf file, or a dbml intermediate file.
Create code from SqlServer:
SqlMetal /server:myserver /database:northwind /code:nwind.cs /namespace:nwind
Generate intermediate dbml file from SqlServer:
SqlMetal /server:myserver /database:northwind /dbml:northwind.dbml /namespace:nwind
Generate code with external mapping from dbml:
SqlMetal /code:nwind.cs /map:nwind.map northwind.dbml
Generate dbml from a SqlCE sdf file:
SqlMetal /dbml:northwind.dbml northwind.sdf
Generate dbml from SqlExpress local server:
SqlMetal /server:."sqlexpress /database:northwind /dbml:northwind.dbml
Generate dbml by using a connection string in the command line:
SqlMetal /conn:"server='myserver'; database='northwind'" /dbml:northwind.dbml
因为sqlmetal已经讲过,不再多讲,大家知道它是个命令行的工具,用来做映射数据库信息的,会使用就可以。再接着讲O/R Designer. 新建任一工程。右击工程,选择add->new item. 如图所示:
弹出item对话框,category中选择data,然后选择Linq to Sql Class, 如图所示:
选择添加。这样,你的工程就多了一个O/R Desiger项目。在菜单View->Sever Explore 打开Sever Explore,添加一个Data Connection, 如图所示:
后,填写数据库服务器,用户名,密码和数据库名。如果,你没有,你可以使用Sql Express 版本。添加之后的效果,如图所示:
打开刚才添加的DataClasses1.dbml 文件,将Sever Explore中的Customer 表或view拖入Designer中来,如图所示:
也可以将Store procedure 和 User define function 拖进来,会在方法面板上形成方法。如图所示:
如果,两个表之间有关系,OR Designer可以显示它们的关系,将Order表和 OderDetail表拖入 如图所示:
打开DataClasses1. Designer.cs 文件,你就可以看到OR Designer给你产生的映射代码了。
System.Data.Linq;
using
System.Data.Linq.Mapping;
using
System.Data;
using
System.Collections.Generic;
using
System.Reflection;
using
System.Linq;
using
System.Linq.Expressions;
using
System.ComponentModel;
using
System;
[System.Data.Linq.Mapping.DatabaseAttribute(Name
=
"
northwind_may06ctp
"
)]
public
partial
class
DataClasses1DataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
Extensibility Method Definitions Extensibility Method Definitions
partial void OnCreated();
partial void InsertOrder(Order instance);
partial void UpdateOrder(Order instance);
partial void DeleteOrder(Order instance);
partial void InsertOrder_Detail(Order_Detail instance);
partial void UpdateOrder_Detail(Order_Detail instance);
partial void DeleteOrder_Detail(Order_Detail instance);
#endregion
static
DataClasses1DataContext()
{
}
public
DataClasses1DataContext(
string
connection) :
base
(connection, mappingSource)
{
OnCreated();
}
public
DataClasses1DataContext(System.Data.IDbConnection connection) :
base
(connection, mappingSource)
{
OnCreated();
}
public
DataClasses1DataContext(
string
connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base
(connection, mappingSource)
{
OnCreated();
}
public
DataClasses1DataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base
(connection, mappingSource)
{
OnCreated();
}
public
DataClasses1DataContext() :
base
(global::SqlMetalUtil.Properties.Settings.Default.northwind_may06ctpConnectionString, mappingSource)
{
OnCreated();
}
public
System.Data.Linq.Table
<
Order
>
Orders
{
get
{
return this.GetTable<Order>();
}
}
public
System.Data.Linq.Table
<
Order_Detail
>
Order_Details
{
get
{
return this.GetTable<Order_Detail>();
}
}
[Function(Name
=
"
dbo.CategoriesInsert
"
)]
public
int
CategoriesInsert([Parameter(Name
=
"
@CategoryID
"
, DbType
=
"
int
"
)] System.Nullable
<
int
>
CategoryID, [Parameter(Name
=
"
@CategoryName
"
, DbType
=
"
nvarchar
"
)]
string
CategoryName, [Parameter(Name
=
"
@Description
"
, DbType
=
"
ntext
"
)]
string
Description, [Parameter(Name
=
"
@Picture
"
, DbType
=
"
image
"
)]
byte
[] Picture)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), CategoryID, CategoryName, Description, Picture);
return ((int)(result.ReturnValue));
}
}
[Table(Name
=
"
dbo.Orders
"
)]
public
partial
class
Order : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _OrderID;
private string _CustomerID;
private System.Nullable<int> _EmployeeID;
private System.Nullable<System.DateTime> _OrderDate;
private System.Nullable<System.DateTime> _RequiredDate;
private System.Nullable<System.DateTime> _ShippedDate;
private System.Nullable<int> _ShipVia;
private System.Nullable<decimal> _Freight;
private string _ShipName;
private string _ShipAddress;
private string _ShipCity;
private string _ShipRegion;
private string _ShipPostalCode;
private string _ShipCountry;
private EntitySet<Order_Detail> _Order_Details;
Extensibility Method Definitions Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate();
partial void OnCreated();
partial void OnOrderIDChanging(int value);
partial void OnOrderIDChanged();
partial void OnCustomerIDChanging(string value);
partial void OnCustomerIDChanged();
partial void OnEmployeeIDChanging(System.Nullable<int> value);
partial void OnEmployeeIDChanged();
partial void OnOrderDateChanging(System.Nullable<System.DateTime> value);
partial void OnOrderDateChanged();
partial void OnRequiredDateChanging(System.Nullable<System.DateTime> value);
partial void OnRequiredDateChanged();
partial void OnShippedDateChanging(System.Nullable<System.DateTime> value);
partial void OnShippedDateChanged();
partial void OnShipViaChanging(System.Nullable<int> value);
partial void OnShipViaChanged();
partial void OnFreightChanging(System.Nullable<decimal> value);
partial void OnFreightChanged();
partial void OnShipNameChanging(string value);
partial void OnShipNameChanged();
partial void OnShipAddressChanging(string value);
partial void OnShipAddressChanged();
partial void OnShipCityChanging(string value);
partial void OnShipCityChanged();
partial void OnShipRegionChanging(string value);
partial void OnShipRegionChanged();
partial void OnShipPostalCodeChanging(string value);
partial void OnShipPostalCodeChanged();
partial void OnShipCountryChanging(string value);
partial void OnShipCountryChanged();
#endregion
public
Order()
{
OnCreated();
this._Order_Details = new EntitySet<Order_Detail>(new Action<Order_Detail>(this.attach_Order_Details), new Action<Order_Detail>(this.detach_Order_Details));
}
[Column(Storage
=
"
_OrderID
"
, AutoSync
=
AutoSync.OnInsert, DbType
=
"
Int NOT NULL IDENTITY
"
, IsPrimaryKey
=
true
, IsDbGenerated
=
true
)]
public
int
OrderID
{
get
{
return this._OrderID;
}
set
{
if ((this._OrderID != value))
{
this.OnOrderIDChanging(value);
this.SendPropertyChanging();
this._OrderID = value;
this.SendPropertyChanged("OrderID");
this.OnOrderIDChanged();
}
}
}
[Column(Storage
=
"
_CustomerID
"
, DbType
=
"
NChar(5)
"
)]
public
string
CustomerID
{
get
{
return this._CustomerID;
}
set
{
if ((this._CustomerID != value))
{
this.OnCustomerIDChanging(value);
this.SendPropertyChanging();
this._CustomerID = value;
this.SendPropertyChanged("CustomerID");
this.OnCustomerIDChanged();
}
}
}
[Column(Storage
=
"
_EmployeeID
"
, DbType
=
"
Int
"
)]
public
System.Nullable
<
int
>
EmployeeID
{
get
{
return this._EmployeeID;
}
set
{
if ((this._EmployeeID != value))
{
this.OnEmployeeIDChanging(value);
this.SendPropertyChanging();
this._EmployeeID = value;
this.SendPropertyChanged("EmployeeID");
this.OnEmployeeIDChanged();
}
}
}
[Column(Storage
=
"
_OrderDate
"
, DbType
=
"
DateTime
"
)]
public
System.Nullable
<
System.DateTime
>
OrderDate
{
get
{
return this._OrderDate;
}
set
{
if ((this._OrderDate != value))
{
this.OnOrderDateChanging(value);
this.SendPropertyChanging();
this._OrderDate = value;
this.SendPropertyChanged("OrderDate");
this.OnOrderDateChanged();
}
}
}
[Column(Storage
=
"
_RequiredDate
"
, DbType
=
"
DateTime
"
)]
public
System.Nullable
<
System.DateTime
>
RequiredDate
{
get
{
return this._RequiredDate;
}
set
{
if ((this._RequiredDate != value))
{
this.OnRequiredDateChanging(value);
this.SendPropertyChanging();
this._RequiredDate = value;
this.SendPropertyChanged("RequiredDate");
this.OnRequiredDateChanged();
}
}
}
[Column(Storage
=
"
_ShippedDate
"
, DbType
=
"
DateTime
"
)]
public
System.Nullable
<
System.DateTime
>
ShippedDate
{
get
{
return this._ShippedDate;
}
set
{
if ((this._ShippedDate != value))
{
this.OnShippedDateChanging(value);
this.SendPropertyChanging();
this._ShippedDate = value;
this.SendPropertyChanged("ShippedDate");
this.OnShippedDateChanged();
}
}
}
[Column(Storage
=
"
_ShipVia
"
, DbType
=
"
Int
"
)]
public
System.Nullable
<
int
>
ShipVia
{
get
{
return this._ShipVia;
}
set
{
if ((this._ShipVia != value))
{
this.OnShipViaChanging(value);
this.SendPropertyChanging();
this._ShipVia = value;
this.SendPropertyChanged("ShipVia");
this.OnShipViaChanged();
}
}
}
[Column(Storage
=
"
_Freight
"
, DbType
=
"
Money
"
)]
public
System.Nullable
<
decimal
>
Freight
{
get
{
return this._Freight;
}
set
{
if ((this._Freight != value))
{
this.OnFreightChanging(value);
this.SendPropertyChanging();
this._Freight = value;
this.SendPropertyChanged("Freight");
this.OnFreightChanged();
}
}
}
[Column(Storage
=
"
_ShipName
"
, DbType
=
"
NVarChar(40)
"
)]
public
string
ShipName
{
get
{
return this._ShipName;
}
set
{
if ((this._ShipName != value))
{
this.OnShipNameChanging(value);
this.SendPropertyChanging();
this._ShipName = value;
this.SendPropertyChanged("ShipName");
this.OnShipNameChanged();
}
}
}
[Column(Storage
=
"
_ShipAddress
"
, DbType
=
"
NVarChar(60)
"
)]
public
string
ShipAddress
{
get
{
return this._ShipAddress;
}
set
{
if ((this._ShipAddress != value))
{
this.OnShipAddressChanging(value);
this.SendPropertyChanging();
this._ShipAddress = value;
this.SendPropertyChanged("ShipAddress");
this.OnShipAddressChanged();
}
}
}
[Column(Storage
=
"
_ShipCity
"
, DbType
=
"
NVarChar(15)
"
)]
public
string
ShipCity
{
get
{
return this._ShipCity;
}
set
{
if ((this._ShipCity != value))
{
this.OnShipCityChanging(value);
this.SendPropertyChanging();
this._ShipCity = value;
this.SendPropertyChanged("ShipCity");
this.OnShipCityChanged();
}
}
}
[Column(Storage
=
"
_ShipRegion
"
, DbType
=
"
NVarChar(15)
"
)]
public
string
ShipRegion
{
get
{
return this._ShipRegion;
}
set
{
if ((this._ShipRegion != value))
{
this.OnShipRegionChanging(value);
this.SendPropertyChanging();
this._ShipRegion = value;
this.SendPropertyChanged("ShipRegion");
this.OnShipRegionChanged();
}
}
}
[Column(Storage
=
"
_ShipPostalCode
"
, DbType
=
"
NVarChar(10)
"
)]
public
string
ShipPostalCode
{
get
{
return this._ShipPostalCode;
}
set
{
if ((this._ShipPostalCode != value))
{
this.OnShipPostalCodeChanging(value);
this.SendPropertyChanging();
this._ShipPostalCode = value;
this.SendPropertyChanged("ShipPostalCode");
this.OnShipPostalCodeChanged();
}
}
}
[Column(Storage
=
"
_ShipCountry
"
, DbType
=
"
NVarChar(15)
"
)]
public
string
ShipCountry
{
get
{
return this._ShipCountry;
}
set
{
if ((this._ShipCountry != value))
{
this.OnShipCountryChanging(value);
this.SendPropertyChanging();
this._ShipCountry = value;
this.SendPropertyChanged("ShipCountry");
this.OnShipCountryChanged();
}
}
}
[Association(Name
=
"
Order_Order_Detail
"
, Storage
=
"
_Order_Details
"
, OtherKey
=
"
OrderID
"
)]
public
EntitySet
<
Order_Detail
>
Order_Details
{
get
{
return this._Order_Details;
}
set
{
this._Order_Details.Assign(value);
}
}
public
event
PropertyChangingEventHandler PropertyChanging;
public
event
PropertyChangedEventHandler PropertyChanged;
protected
virtual
void
SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected
virtual
void
SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private
void
attach_Order_Details(Order_Detail entity)
{
this.SendPropertyChanging();
entity.Order = this;
this.SendPropertyChanged("Order_Details");
}
private
void
detach_Order_Details(Order_Detail entity)
{
this.SendPropertyChanging();
entity.Order = null;
this.SendPropertyChanged("Order_Details");
}
}
[Table(Name
=
"
dbo.[Order Details]
"
)]
public
partial
class
Order_Detail : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _OrderID;
private int _ProductID;
private decimal _UnitPrice;
private short _Quantity;
private float _Discount;
private EntityRef<Order> _Order;
Extensibility Method Definitions Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate();
partial void OnCreated();
partial void OnOrderIDChanging(int value);
partial void OnOrderIDChanged();
partial void OnProductIDChanging(int value);
partial void OnProductIDChanged();
partial void OnUnitPriceChanging(decimal value);
partial void OnUnitPriceChanged();
partial void OnQuantityChanging(short value);
partial void OnQuantityChanged();
partial void OnDiscountChanging(float value);
partial void OnDiscountChanged();
#endregion
public
Order_Detail()
{
OnCreated();
this._Order = default(EntityRef<Order>);
}
[Column(Storage
=
"
_OrderID
"
, DbType
=
"
Int NOT NULL
"
, IsPrimaryKey
=
true
)]
public
int
OrderID
{
get
{
return this._OrderID;
}
set
{
if ((this._OrderID != value))
{
if (this._Order.HasLoadedOrAssignedValue)
{
throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
}
this.OnOrderIDChanging(value);
this.SendPropertyChanging();
this._OrderID = value;
this.SendPropertyChanged("OrderID");
this.OnOrderIDChanged();
}
}
}
[Column(Storage
=
"
_ProductID
"
, DbType
=
"
Int NOT NULL
"
, IsPrimaryKey
=
true
)]
public
int
ProductID
{
get
{
return this._ProductID;
}
set
{
if ((this._ProductID != value))
{
this.OnProductIDChanging(value);
this.SendPropertyChanging();
this._ProductID = value;
this.SendPropertyChanged("ProductID");
this.OnProductIDChanged();
}
}
}
[Column(Storage
=
"
_UnitPrice
"
, DbType
=
"
Money NOT NULL
"
)]
public
decimal
UnitPrice
{
get
{
return this._UnitPrice;
}
set
{
if ((this._UnitPrice != value))
{
this.OnUnitPriceChanging(value);
this.SendPropertyChanging();
this._UnitPrice = value;
this.SendPropertyChanged("UnitPrice");
this.OnUnitPriceChanged();
}
}
}
[Column(Storage
=
"
_Quantity
"
, DbType
=
"
SmallInt NOT NULL
"
)]
public
short
Quantity
{
get
{
return this._Quantity;
}
set
{
if ((this._Quantity != value))
{
this.OnQuantityChanging(value);
this.SendPropertyChanging();
this._Quantity = value;
this.SendPropertyChanged("Quantity");
this.OnQuantityChanged();
}
}
}
[Column(Storage
=
"
_Discount
"
, DbType
=
"
Real NOT NULL
"
)]
public
float
Discount
{
get
{
return this._Discount;
}
set
{
if ((this._Discount != value))
{
this.OnDiscountChanging(value);
this.SendPropertyChanging();
this._Discount = value;
this.SendPropertyChanged("Discount");
this.OnDiscountChanged();
}
}
}
[Association(Name
=
"
Order_Order_Detail
"
, Storage
=
"
_Order
"
, ThisKey
=
"
OrderID
"
, IsForeignKey
=
true
)]
public
Order Order
{
get
{
return this._Order.Entity;
}
set
{
Order previousValue = this._Order.Entity;
if (((previousValue != value)
|| (this._Order.HasLoadedOrAssignedValue == false)))
{
this.SendPropertyChanging();
if ((previousValue != null))
{
this._Order.Entity = null;
previousValue.Order_Details.Remove(this);
}
this._Order.Entity = value;
if ((value != null))
{
value.Order_Details.Add(this);
this._OrderID = value.OrderID;
}
else
{
this._OrderID = default(int);
}
this.SendPropertyChanged("Order");
}
}
}
public
event
PropertyChangingEventHandler PropertyChanging;
public
event
PropertyChangedEventHandler PropertyChanged;
protected
virtual
void
SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected
virtual
void
SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
本节介绍了O/R Designer的基本用法,下节讲一些比较高级的用法。O/R Designer相对与sqlmetal的好处就可以设计类的继承关系(下节再讲),而sqlmetal 相对于O/R Designer是可以一次性抽提所有表的信息,快速便捷。而且sqlmetal支持一些O/R Designer无法支持的信息提取。