LINQ to SQL(2):生成物件模型
在LINQ to SQL中,可以使用自己的程式語言的物件模型對映到關係資料庫,在上一節課,已經有一部分內容,簡單的介紹了一下這種物件模型的結構,這一節,我們主要講使用vs給我們提供的工具來生成物件模型的方法
在visual studio中,可以使用OR設計器提供的豐富的使用者介面來幫助我們生成您自定義的物件模型,這裡寫一下具體的操作步驟
在我們建立的專案上,右擊,點選新增新項
在“資料”的NODE上點選“LINQ to SQL類”,資料想用的名字,點選“新增”
這時,在VS中會出現一個空白的圖形介面,我們可以通過拖動伺服器資源管理器中的表,儲存過程來自動生成一些對於資料庫的對映,不像我們第一節中用到的,這裡所有的資料對映都是由OR設計器自動生成的,大大的提高了我們的開發效率,如果這時開啟dbml下的xxx.designer.cs,我們會發現,這個類就是繼承子DataContext,和我們上一節的方式是一樣的
開啟伺服器資源管理器,在資料連線上點選右鍵,選擇新增連線,會彈出選擇資料來源的視窗,這裡我就不多加贅述啦,直接跳到新增完資料庫的連線以後,這裡要注意需要把我們需要的表、檢視、儲存過程在建立連線是新增進來
在伺服器資源管理器中,找到我們剛才建立的資料庫連線,然後開啟“表”選項卡,然後拖動Customers表到OR設計器的左邊
這時開啟xxx.designer.cs,會發現了類似如下程式碼
[Table(Name="dbo.Customers")] public partial class Customers : INotifyPropertyChanging, INotifyPropertyChanged { private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); private string _CustomerID; private string _CompanyName; private string _ContactName; private string _ContactTitle; private string _Address; private string _City; private string _Region; private string _PostalCode; private string _Country; private string _Phone; private string _Fax; #region Extensibility Method Definitions partial void OnLoaded(); partial void OnValidate(System.Data.Linq.ChangeAction action); partial void OnCreated(); partial void OnCustomerIDChanging(string value); partial void OnCustomerIDChanged(); partial void OnCompanyNameChanging(string value); partial void OnCompanyNameChanged(); partial void OnContactNameChanging(string value); partial void OnContactNameChanged(); partial void OnContactTitleChanging(string value); partial void OnContactTitleChanged(); partial void OnAddressChanging(string value); partial void OnAddressChanged(); partial void OnCityChanging(string value); partial void OnCityChanged(); partial void OnRegionChanging(string value); partial void OnRegionChanged(); partial void OnPostalCodeChanging(string value); partial void OnPostalCodeChanged(); partial void OnCountryChanging(string value); partial void OnCountryChanged(); partial void OnPhoneChanging(string value); partial void OnPhoneChanged(); partial void OnFaxChanging(string value); partial void OnFaxChanged(); #endregion public Customers() { OnCreated(); } [Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)] 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="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)] public string CompanyName { get { return this._CompanyName; } set { if ((this._CompanyName != value)) { this.OnCompanyNameChanging(value); this.SendPropertyChanging(); this._CompanyName = value; this.SendPropertyChanged("CompanyName"); this.OnCompanyNameChanged(); } } } [Column(Storage="_ContactName", DbType="NVarChar(30)")] public string ContactName { get { return this._ContactName; } set { if ((this._ContactName != value)) { this.OnContactNameChanging(value); this.SendPropertyChanging(); this._ContactName = value; this.SendPropertyChanged("ContactName"); this.OnContactNameChanged(); } } } [Column(Storage="_ContactTitle", DbType="NVarChar(30)")] public string ContactTitle { get { return this._ContactTitle; } set { if ((this._ContactTitle != value)) { this.OnContactTitleChanging(value); this.SendPropertyChanging(); this._ContactTitle = value; this.SendPropertyChanged("ContactTitle"); this.OnContactTitleChanged(); } } } [Column(Storage="_Address", DbType="NVarChar(60)")] public string Address { get { return this._Address; } set { if ((this._Address != value)) { this.OnAddressChanging(value); this.SendPropertyChanging(); this._Address = value; this.SendPropertyChanged("Address"); this.OnAddressChanged(); } } } [Column(Storage="_City", DbType="NVarChar(15)")] public string City { get { return this._City; } set { if ((this._City != value)) { this.OnCityChanging(value); this.SendPropertyChanging(); this._City = value; this.SendPropertyChanged("City"); this.OnCityChanged(); } } } [Column(Storage="_Region", DbType="NVarChar(15)")] public string Region { get { return this._Region; } set { if ((this._Region != value)) { this.OnRegionChanging(value); this.SendPropertyChanging(); this._Region = value; this.SendPropertyChanged("Region"); this.OnRegionChanged(); } } } [Column(Storage="_PostalCode", DbType="NVarChar(10)")] public string PostalCode { get { return this._PostalCode; } set { if ((this._PostalCode != value)) { this.OnPostalCodeChanging(value); this.SendPropertyChanging(); this._PostalCode = value; this.SendPropertyChanged("PostalCode"); this.OnPostalCodeChanged(); } } } [Column(Storage="_Country", DbType="NVarChar(15)")] public string Country { get { return this._Country; } set { if ((this._Country != value)) { this.OnCountryChanging(value); this.SendPropertyChanging(); this._Country = value; this.SendPropertyChanged("Country"); this.OnCountryChanged(); } } } [Column(Storage="_Phone", DbType="NVarChar(24)")] public string Phone { get { return this._Phone; } set { if ((this._Phone != value)) { this.OnPhoneChanging(value); this.SendPropertyChanging(); this._Phone = value; this.SendPropertyChanged("Phone"); this.OnPhoneChanged(); } } } [Column(Storage="_Fax", DbType="NVarChar(24)")] public string Fax { get { return this._Fax; } set { if ((this._Fax != value)) { this.OnFaxChanging(value); this.SendPropertyChanging(); this._Fax = value; this.SendPropertyChanged("Fax"); this.OnFaxChanged(); } } } 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)); } } }
在這個類裡,除了我們在上一節裡的寫到的資料表,表中的列在物件中的對映意外,還有一些事件以及一些抽象方法,這裡的事件會在我們對物件模型中的資料做了更改以後觸發的,這樣,在我們呼叫SubmitChange的時候,模型就會知道有那些屬性有更改過,然後把這個更改寫回給資料庫,這個我想我會在下一節中重點寫到,所以這裡就不多做解釋啦,只需要知道他的功能就好了
然後,我們再把一個另一個Orders表拖拽到OR設計器中
我們看到,設計器已經自動幫我們實現了兩個表之間的主外來鍵關係,再次開啟xxx.designer.cs,
我們可以在兩個生成的實體類中找到類似如下內容:
[Association(Name="Customers_Orders", Storage="_Orders", ThisKey="CustomerID", OtherKey="CustomerID")] public EntitySet<Orders> Orders { get { return this._Orders; } set { this._Orders.Assign(value); } }
是不是很熟悉呢,就是我們在第一節裡自己寫過的主外來鍵關係的對映,不多做解釋
同樣,我們不僅可以利用OR設計器建立表的對映,而且也可以建立檢視的對映、儲存過程的對映,這裡需要注意的是,如果我們要建立儲存過程的對映,在模型裡生成的是一個方法,而不是一個類物件
[Function(Name="dbo.CustOrderHist")]
public ISingleResult<CustOrderHist_個結果> CustOrderHist([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
return ((ISingleResult<CustOrderHist_個結果>)(result.ReturnValue));
}
同時,也會生成一個類,這個類是對應這個方法的返回結果的,也就是說,如果我們呼叫的一個儲存過程有返回結果,我們同樣可以使用LINQ to SQL返回一個強型別化的物件
怎麼樣,如果在上一節中LINQ to SQL的查詢方式讓你耳目一新、心潮澎湃的話,那麼OR設計器的方便快捷,是不是讓你有一種令狐沖在西湖水牢牢底摸到了任天行留下的吸星大法的感覺呢