之前把自己写过的一个简单ORM类库介绍了下,考虑到代码会有改动而blog中编辑代码太麻烦,在CodePlex上建了一个项目:MyORM,相关代码和文件维护起来方便不少。
CodePlex下载地址http://www.codeplex.com/MyOrm/Release/ProjectReleases.aspx?ReleaseId=18323,包含了源码、一个Sample工程和CodeSmith的模板文件。
简单说一下自己写ORM的目的,个人不喜欢把实体对象搞得太复杂,因为在系统中实体是作为数据载体存在的,如果还要让它负责数据库操作、实体关系,往往会造成很多问题。
另外就是现有的ORM并不是太好用,比如说在显示到界面时不方便,或者效率太低,我的方法是给实体类型定义一个View用来显示。还有查询也不是很好用,我的想法是简单的查询可以定义统一的查询方式,复杂的查询通过自己写SQL然后封装成方法,如果复杂的查询还要定义成统一的方式那就另外自己开发吧。
以Northwind的数据库做例子,实体的定义可能是下面这样:
- [Table("Products")]
- [Serializable]
- public class Products
- {
- #region Member Variables
- private int productID;
- private string productName;
- private int? supplierID;
- private int? categoryID;
- private string quantityPerUnit;
- private decimal? unitPrice;
- private short? unitsInStock;
- private short? unitsOnOrder;
- private short? reorderLevel;
- private bool discontinued;
- #endregion
- #region Public Properties
- [Column(IsPrimaryKey = true)]
- public int ProductID
- {
- get { return productID; }
- set { productID = value; }
- }
- [Column]
- public string ProductName
- {
- get { return productName; }
- set { productName = value; }
- }
- [Column]
- public int? SupplierID
- {
- get { return supplierID; }
- set { supplierID = value; }
- }
- [Column]
- public int? CategoryID
- {
- get { return categoryID; }
- set { categoryID = value; }
- }
- [Column]
- public string QuantityPerUnit
- {
- get { return quantityPerUnit; }
- set { quantityPerUnit = value; }
- }
- [Column]
- public decimal? UnitPrice
- {
- get { return unitPrice; }
- set { unitPrice = value; }
- }
- [Column]
- public short? UnitsInStock
- {
- get { return unitsInStock; }
- set { unitsInStock = value; }
- }
- [Column]
- public short? UnitsOnOrder
- {
- get { return unitsOnOrder; }
- set { unitsOnOrder = value; }
- }
- [Column]
- public short? ReorderLevel
- {
- get { return reorderLevel; }
- set { reorderLevel = value; }
- }
- [Column]
- public bool Discontinued
- {
- get { return discontinued; }
- set { discontinued = value; }
- }
- #endregion
- }
而在显示到界面的时候直接显示SupplierID和CategoryID是不合适的,而应该显示对应对象的名称或者其他内容,因此需要再定义一个View:
- [TableJoin(typeof(Categories), "CategoryID", AliasName = ProductsView.Category)]
- [TableJoin(typeof(Suppliers), "SupplierID", AliasName = ProductsView.Supplier)]
- public class ProductsView : Products
- {
- #region Constant
- public const string Category = "Category";
- public const string Supplier = "Supplier";
- #endregion
- #region Member Variables
- private string category_CategoryName;
- private string category_Description;
- private byte[] category_Picture;
- private string supplier_CompanyName;
- private string supplier_ContactName;
- private string supplier_ContactTitle;
- private string supplier_Address;
- private string supplier_City;
- private string supplier_Region;
- private string supplier_PostalCode;
- private string supplier_Country;
- private string supplier_Phone;
- private string supplier_Fax;
- private string supplier_HomePage;
- #endregion
- #region Public Properties
- [Column("CategoryName", Foreign = ProductsView.Category, ColumnMode = ColumnMode.Read)]
- public string Category_CategoryName
- {
- get { return category_CategoryName; }
- set { category_CategoryName = value; }
- }
- [Column("Description", Foreign = ProductsView.Category, ColumnMode = ColumnMode.Read)]
- public string Category_Description
- {
- get { return category_Description; }
- set { category_Description = value; }
- }
- [Column("Picture", Foreign = ProductsView.Category, ColumnMode = ColumnMode.Read)]
- public byte[] Category_Picture
- {
- get { return category_Picture; }
- set { category_Picture = value; }
- }
- [Column("CompanyName", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_CompanyName
- {
- get { return supplier_CompanyName; }
- set { supplier_CompanyName = value; }
- }
- [Column("ContactName", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_ContactName
- {
- get { return supplier_ContactName; }
- set { supplier_ContactName = value; }
- }
- [Column("ContactTitle", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_ContactTitle
- {
- get { return supplier_ContactTitle; }
- set { supplier_ContactTitle = value; }
- }
- [Column("Address", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_Address
- {
- get { return supplier_Address; }
- set { supplier_Address = value; }
- }
- [Column("City", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_City
- {
- get { return supplier_City; }
- set { supplier_City = value; }
- }
- [Column("Region", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_Region
- {
- get { return supplier_Region; }
- set { supplier_Region = value; }
- }
- [Column("PostalCode", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_PostalCode
- {
- get { return supplier_PostalCode; }
- set { supplier_PostalCode = value; }
- }
- [Column("Country", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_Country
- {
- get { return supplier_Country; }
- set { supplier_Country = value; }
- }
- [Column("Phone", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_Phone
- {
- get { return supplier_Phone; }
- set { supplier_Phone = value; }
- }
- [Column("Fax", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_Fax
- {
- get { return supplier_Fax; }
- set { supplier_Fax = value; }
- }
- [Column("HomePage", Foreign = ProductsView.Supplier, ColumnMode = ColumnMode.Read)]
- public string Supplier_HomePage
- {
- get { return supplier_HomePage; }
- set { supplier_HomePage = value; }
- }
- #endregion
- }
然后在使用的时候像下面这样:
- dataGridView1.DataSource = new ProductsViewDAO().Search(null);
就可以显示所有ProductsView的内容。Products和ProductsView是通过CodeSmith生成,完全可以按照自己的需要修改。
ProductsDAO和ProductsViewDAO下次再介绍。