首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

走進 LINQ:LINQ to SQL How Do I (3) — 對應設定全解析

     編輯:關於.NET

NHibernate 使用 XML 設定對應,Castle ActiveRecord(底層仍用 NHibernate)採用 Attribute 方式。一個非侵入式、一個侵入式。有人偏好 XML 彈性免重新編譯,有人偏好 Attribute 可維護性佳且具編譯期檢查。

在 LINQ to SQL 中,這兩種方式皆支援,且走得更遠,提供四種對應設定途徑:

  1. 純 Attribute 方式
  2. XML 檔案設定
  3. SqlMetal 命令列工具產生程式碼
  4. Visual Studio 設計器產生對應程式碼

純 Attribute 方式設定

對應 Attribute 位於 System.Data.Linq.Mapping 命名空間。常用 Attribute:Table、Column、Association,另有 Database、Provider、Function 等。

TableAttribute

套用於類別,不可重複、不可繼承。定義類別與資料表對應。若類別未標註 Table,即使屬性標註 Column 也無效,執行時會拋出 InvalidOperationException。唯一屬性 Name 用於類別名與資料表名不同時指定表名。

ColumnAttribute

屬性豐富,命名直觀易懂。

AutoSync

列舉型別:Default、Always、Never、OnInsert、OnUpdate。控制執行 Insert/Update 後,屬性如何與資料庫被修改欄位同步。

  • Default:預設,若欄位有預設值且 IsDbGenerated=true 則同步。
  • Always:總是同步。
  • Never:從不同步。
  • OnInsert:插入後同步(如自增主鍵)。
  • OnUpdate:更新時同步。

實測:預設情況下插入後會自動查回 IsDbGenerated=true 的欄位(如身分識別欄位)。若將 Title 設為 AutoSync.Always,插入後也會查回 Title。

CanBeNull

指定對應資料庫欄位是否允許 NULL。若不允許而指派 null 會拋出例外。注意:NULL 不等於空字串或零。

DbType

若使用 CreateDatabase 從對應類別建立資料表,建議明確指定,避免 LINQ to SQL 從屬性型別推斷導致不精確。例:[Column(DbType="NVarchar(50) not null")] public string Title。這也意味著可先設計領域物件再建立資料庫(真正的 ORM)。

Expression

表示計算欄位。例:資料庫存美元價格,取出時自動換算人民幣:[Column(Expression="price * 6")] public float Price。注意:匯率波動時硬編碼不可取,僅示範用法。

IsDbGenerated

標示屬性值由資料庫產生(如自增欄位、有預設值的欄位),程式碼無需指派。

IsPrimaryKey

標示主鍵。複合主鍵可在多個屬性上標註。

IsVersion 與 UpdateCheck

樂觀並行控制相關,後續詳述。

Name

屬性名與欄位名不一致時指定欄位名。

Storage

當屬性 setter 包含複雜邏輯,但從資料庫取值時不想執行 setter,可指定私有欄位名稱:

private float _price;
[Column(Storage="_price")]
public float Price {
    get { return _price; }
    set { _price = value * 20; } // 複雜邏輯
}

AssociationAttribute

建立實體間關聯。範例:

[Association(ThisKey="Id", OtherKey="BlogId")]
public EntitySet<Post> Posts { get; set; }

核心屬性:ThisKey(本端關聯鍵,預設為 IsPrimaryKey 屬性)、OtherKey(關聯端鍵,預設為關聯類別的識別欄位)。繼承自 DataAttribute,也有 Name(建立資料庫關聯時用)與 Storage。

XML 檔案設定方式

DataContext 有多載建構子:DataContext(string, MappingSource)。MappingSource 為抽象類別,兩個實作:AttributeMappingSource(預設)與 XmlMappingSource。

使用 XML 對應:

XmlMappingSource mapping = XmlMappingSource.FromXml(File.ReadAllText(@"e:\cnblogs\map.xml"));
DataContext dbContext = new DataContext(connectionString, mapping);

XML 格式範例:

<?xml version="1.0" encoding="utf-16"?>
<Database Name="Cnblogs" xmlns="https://schemas.microsoft.com/linqtosql/mapping/2007">
  <Table Name="posts">
    <Type Name="Yuyijq.Linq.Cnblogs.Domain.Post">
      <Column Name="postid" Member="Id" IsPrimaryKey="true" IsDbGenerated="true" />
      <Column Name="blogid" Member="BlogId" />
      <Column Name="title" Member="Title" />
      <Column Name="body" Member="Body" />
      <Column Name="createdate" Member="CreateDate" IsDbGenerated="true"/>
    </Type>
  </Table>
</Database>

結構:Database → Table → Type → Column/Association。與 Attribute 方式對應,多一個 Member 指定實體屬性。

SqlMetal 命令列工具

可整合 MSBuild 實現自動化。支援 /serialization: 開關(None 或 Unidirectional),產生可序列化實體類別(適合 WCF/Web Service 傳遞)。詳細用法輸入 SqlMetal /? 查詢。

Visual Studio 設計器

專案中新增「LINQ to SQL 類別」項目,從伺服器總管拖曳資料表至設計面,工具列建立關聯。產生三個檔案:

  • .dbml:XML 格式對應檔
  • .cs:部分類別程式碼,與 .dbml 共同編譯
  • .layout:設計器版面資訊,不影響程式

後記

原計劃三篇完成 How Do I,內容較多拆分為四篇。下一篇將詳細介紹 DataContext、Update/Delete 時的 RowVersion、交易與延遲載入/執行等主題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved