有的时候我们在设计数据库的时候发现如果完全把商务逻辑中的类影射到表中可能会照成数据库中很多表都很相似,甚至结构上都是一样的,下面举一个例子来说明如何处理这种情况。假设我们正在创建一个图书销售网站,但客户却希望这个图书销售网站可能需要销售其他产品,在业务逻辑层我们可能设计如下:
表结构设计如下:
那么如何映射对象和表呢,请看如下代码:
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;
}
}
}
}
[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类:
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;
}
}
}
}
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类
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;
}
}
}
}
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)
{
}
}
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();
}
}
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();
}
}
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语句为:
如果我们需要检索所有图书代码如下:
检索所有书
static void Main(string[] args)
{
using (MyDataContext dc = new MyDataContext(MyDataContext.connString))
{
var b = from x in dc.Products
where x is Book
select x;
foreach (var item in b)
{
Console.WriteLine(item.Name);
}
}
}
static void Main(string[] args)
{
using (MyDataContext dc = new MyDataContext(MyDataContext.connString))
{
var b = from x in dc.Products
where x is Book
select x;
foreach (var item in b)
{
Console.WriteLine(item.Name);
}
}
}