有的時候我們在設計數據庫的時候發現如果完全把商務邏輯中的類影射到表中可能會照成數據庫中很多表都很相似,甚至結構上都是一樣的,下面舉一個例子來說明如何處理這種情況。假設我們正在創建一個圖書銷售網站,但客戶卻希望這個圖書銷售網站可能需要銷售其他產品,在業務邏輯層我們可能設計如下:
表結構設計如下:
那麼如何映射對象和表呢,請看如下代碼:
Product
[Table(Name = "dbo.Products")] [InheritanceMapping(Code = "1", Type = typeof(Product), IsDefault = true)] [InheritanceMapping(Code = "2", Type = typeof(Book))] [InheritanceMapping(Code = "3", Type = typeof(OtherProduct))] public partial class Product { private int _ProductID; private string _Name; private System.Nullable<int> _Stock; private System.Nullable<decimal> _Price; private string _TypeID; public Product() { } [Column(Storage = "_ProductID", DbType = "Int NOT NULL", IsPrimaryKey = true)] public int ProductID { get { return this._ProductID; } set { if ((this._ProductID != value)) { this._ProductID = value; } } } [Column(Storage = "_Name", DbType = "VarChar(50)")] public string Name { get { return this._Name; } set { if ((this._Name != value)) { this._Name = value; } } } [Column(Storage = "_Stock", DbType = "Int")] public System.Nullable<int> Stock { get { return this._Stock; } set { if ((this._Stock != value)) { this._Stock = value; } } } [Column(Storage = "_Price", DbType = "Decimal(18,2)")] public System.Nullable<decimal> Price { get { return this._Price; } set { if ((this._Price != value)) { this._Price = value; } } } [Column(IsDiscriminator = true, Storage = "_TypeID", DbType = "VarChar(50)")] public string TypeID { get { return this._TypeID; } set { if ((this._TypeID != value)) { this._TypeID = value; } } } }
book類:
partial class Book:Product { private string _Author; private string _ISBN; [Column(Storage = "_ISBN", DbType = "VarChar(50)")] public string ISBN { get { return this._ISBN; } set { if ((this._ISBN != value)) { this._ISBN = value; } } } [Column(Storage = "_Author", DbType = "VarChar(50)")] public string Author { get { return this._Author; } set { if ((this._Author != value)) { this._Author = value; } } } }
OtherProduct類
partial class OtherProduct : Product { private string _ProductFrom; [Column(Storage = "_ProductFrom", DbType = "VarChar(50)")] public string ProductFrom { get { return this._ProductFrom; } set { if ((this._ProductFrom != value)) { this._ProductFrom = value; } } } }
數據上下文
public partial class MyDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
private readonly static string dbPath = Path.GetFullPath(Path.Combine(".", @"..\..\Data\DatabaseTest.MDF"));
private readonly static string sqlServerInstance = @".\SQLEXPRESS";
public readonly static string connString = "AttachDBFileName='" + dbPath + "';Server='" + sqlServerInstance + "';user instance=true;Integrated Security=SSPI;Connection Timeout=60";
public System.Data.Linq.Table<Product> Products
{
get
{
return this.GetTable<Product>();
}
}
public MyDataContext(string connection) :
base(connection, mappingSource)
{
}
}
這裡最好將數據上下文以及product類從dbml文件中分離出來,因為這裡邊有一部分需要我們自己定義。這裡邊主要需要我們自定義的部分就是product類,需要在類前添加如下特性:
[InheritanceMapping(Code = "1", Type = typeof(Product), IsDefault = true)] [InheritanceMapping(Code = "2", Type = typeof(Book))] [InheritanceMapping(Code = "3", Type = typeof(OtherProduct))]
還有就是用於區分的屬性TypeID前也要修改特性如下:
[Column(IsDiscriminator = true, Storage = "_TypeID", DbType = "VarChar(50)")]
應用:
如果我們需要添加一本書到數據庫中我們可以使用如下代碼
添加一本書
static void Main(string[] args) { using (MyDataContext dc = new MyDataContext(MyDataContext.connString)) { Book b = new Book() { ProductID = 1, Price = 20, Author = "lfm", ISBN = "123456", Name = "c#", Stock = 100 }; dc.Log = Console.Out; dc.Products.InsertOnSubmit(b); dc.SubmitChanges(); } }
在這裡我們可以查看sql語句為:
如果我們需要添加一個其他產品到數據庫我們可以使用如下代碼:
添加其他商品
static void Main(string[] args) { using (MyDataContext dc = new MyDataContext(MyDataContext.connString)) { OtherProduct p = new OtherProduct() { ProductID = 2, Price = 20, Name = "c#", Stock = 100,ProductFrom="bj"}; dc.Log = Console.Out; dc.Products.InsertOnSubmit(p); dc.SubmitChanges(); } }
在這裡我們可以查看sql語句為:
如果我們需要檢索所有圖書代碼如下:
檢索所有書
staticvoidMain(string[]args) { using(MyDataContextdc=newMyDataContext(MyDataContext.connString)) { varb=fromxindc.Products wherexisBook selectx; foreach(variteminb) { Console.WriteLine(item.Name); } } }