一. 前言
Websharp的目標,是開發一個開源的基於Microsoft.Net的輕量級的應用軟件系統開發框架,包含以下內容:
Ø 一個輕量級的O/R Mapping框架
Ø 一個輕量級的AOP框架
Ø 一個輕量級的ServiceLocator,主要目的是爲整合不同服務端技術的客戶端編程。
二. Websharp O/R Mapping起步
Websharp ORM是一個輕量級的O/R Mapping框架,主要特點是拋棄了Java中常見的,也是其他一些O/R Mapping產品中使用XML文件來做映射描述的方法,而使用Attribute作爲描述映射的方法,簡單明瞭,並且,對開發人員來說,只有PersistenceManager、Query、Transaction等極少數接口需要掌握,上手快,使用非常方便。
因爲在某些地方使用了範型,所以目前版本的Websharp需要.Net Framework2.0。
下面的例子給出了使用Websharp進行ORM操作的基本過程。
使用Visual Studio.Net2005建立一個Windows Console項目,然後,定義如下一個類:
[TableMap("Product", "ID")] public class Product { private int m_ID; private string m_Name; private decimal m_Price; public Product() { } public Product(string name,decimal price) { //m_ID = id; m_Name = name; m_Price = price; } [ColumnMap("ID", DbType.Int32)] [AutoIncrease(1)] public int ID { get { return m_ID; } set { m_ID = value; } } [ColumnMap("Name", DbType.String)] public string Name { get { return m_Name; } set { m_Name = value; } } [ColumnMap("Price", DbType.Decimal)] public decimal Price { get { return m_Price; } set { m_Price = value; } } } |
類中第一行[TableMap("Product", "ID")]的意思是說,這個Product類映射到數據庫中的Product表,主鍵爲屬性ID。在屬性ID上,[ColumnMap("ID", DbType.Int32)]的意思是說,這個屬性映射到數據庫中的ID字段,數據類型是Int32,[AutoIncrease(1)]表明這是一個自動增長列,增長的幅度爲1。其他屬性的可以據此類推。
因此,上面這個Produc類對應的數據庫表的結構應該是:
字段名 |
數據類型 |
ID |
int(自動增長) |
Name |
Nvarchar(50) |
Price |
Decimal |
下面的代碼演示了Websharp是如何把Product對象新增到數據庫中的。
public static void { //設定環境 DatabaseProperty dbp = new DatabaseProperty(); dbp.DatabaseType = DatabaseType.MSSQLServer; dbp.ConnectionString = "Data Source=(local);Initial Catalog=WebsharpTest;Integrated Security=True"; //操作數據 PersistenceManager pm = PersistenceManagerFactory.Instance().Create(dbp); Product p0 = new Product("Name0", 100); pm.PersistNew(p0); Product p1 = new Product("Name1", 101); pm.PersistNew(p1); pm.Flush(); pm.Close(); } |
在代碼的開始部分,先設定了數據庫的一些參數,然後,通過PersistenceManagerFactory創建了一個PersistenceManager,用這個PersistenceManager就可以對對象進行操作了。在上面的代碼裏面,我們把兩個Product對象保存到了數據庫中。注意,因爲Product類的ID屬性是自動增長的,因此,在保存這兩個對象之前,是不必對ID屬性賦值的,在這兩個對象被保存到數據庫中後,PersistenceManager會根據數據庫中的自動增長的值自動給ID賦值。
當然,爲了使上面的代碼能夠順利運行,我們還需要做一些配置。新建一個App.config文件,把下面的配置代碼Copy進去就可以了:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings,
Microsoft.Practices.EnterpriseLibrary.Caching, Version= <section name="WebsharpExpirationPolicy" type="Websharp.ORM.Service.WebsharpCofigurationHandler,Websharp.ORM.Service" /> </configSections> <cachingConfiguration defaultCacheManager="Cache Manager"> <cacheManagers> <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="Null Storage" name="Cache Manager" /> <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="Null Storage" name="EntityCache" /> <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="Null Storage" name="SqlCache" /> </cacheManagers> <backingStores> <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore,
Microsoft.Practices.EnterpriseLibrary.Caching, Version= name="Null Storage" /> </backingStores> </cachingConfiguration> <WebsharpExpirationPolicy> <ExpirationPolicy ExpirationCheckInterval="60" AssemblyName="Microsoft.ApplicationBlocks.Cache" ClassName="Microsoft.ApplicationBlocks.Cache.ExpirationsImplementations.SlidingTime" /> </WebsharpExpirationPolicy> </configuration> |
配置文件只是用來說明緩存的使用的,基本上所有的項目需要的配置文件對於Websharp來說都不需要改變。當然,有一些細微的參數還是可以調整的,這個在後面描述。
可以看出,相對於其他一些O/R Mapping框架來說,Websharp不需要寫一大堆的XML映射文件,代碼簡潔明瞭。
三. 映射方法說明
映射部分,完成對象和關係型數據庫之間映射關係的表達。Websharp使用Attribute來描述映射關係,設計了以下Attribute來描述對象和關係型數據庫之間的映射。
Ø TableMapAttribute
這個Attribute描述對象和數據庫表的映射關係,這個類有兩個屬性,TableName屬性指明和某個類所對應的數據庫表,PrimaryKeys用來描述表的主關鍵字。這個類的定義如下:
[AttributeUsage(AttributeTargets.Class)] public class TableMapAttribute : Attribute { private string tableName; private string[] primaryKeys; public TableMapAttribute(string tableName,params string[] primaryKeys) { this.tableName = tableName; this.primaryKeys = primaryKeys; } public string TableName { get{return tableName;} set{tableName = value;} }
public string[] PrimaryKeys { get{return primaryKeys;} set{primaryKeys = value;} } } |
Ø ColumnMapAttribute
這個Attribute描述對象屬性和數據庫中表的字段之間的映射關係,這個類有三個屬性,ColumnName屬性指明和某個屬性所對應的字段,DbType屬性指明數據庫字段的數據類型,DefaultValue指明字段的默認值。這個類的定義如下:
[AttributeUsage(AttributeTargets.Property)] public class ColumnMapAttribute : Attribute { private string columnName; private DbType dbtype; private object defaultValue; public ColumnMapAttribute(string columnName,DbType dbtype) { this.columnName = columnName; this.dbtype = dbtype; } public ColumnMapAttribute(string columnName,DbType dbtype,object defaultValue) { this.columnName = columnName; this.dbtype = dbtype; this.defaultValue = defaultValue; } public string ColumnName { get{return columnName;} set{columnName = value;} } public DbType DbType { get{return dbtype;} set{dbtype = value;} }
public object DefaultValue { get{return defaultValue;} set{defaultValue = value;} } } |
Ø ReferenceObjectAttribute
ReferenceObjectAttribute指示該屬性是引用的另外一個對象,因此,在執行持久化操作的時候,需要根據參數進行額外的處理。默認情況下,當持久化實體對象的時候,ReferenceObjectAttribute指示的屬性,不進行操作。這個類有三個屬性,ReferenceType指明所引用的對象的類型,PrimaryKey和ForeignKey用來指明兩個類之間進行關聯的主鍵和外鍵。這個類的定義如下:
[AttributeUsage(AttributeTargets.Property)] public class ReferenceObjectAttribute : Attribute { private Type referenceType; private string primaryKey; private string foreignKey; public ReferenceObjectAttribute(Type referenceType,string primaryKey,string foreignKey) { this.referenceType = referenceType; this.primaryKey = primaryKey; this.foreignKey = foreignKey; } public ReferenceObjectAttribute(){} public Type ReferenceType { get{return referenceType;} set{referenceType = value;} } public string PrimaryKey { get{return primaryKey;} set{primaryKey = value;} } public string ForeignKey { get{return foreignKey;} set{foreignKey = value;} } } |
Ø SubObjectAttribute
SubObjectAttribute指示該屬性是引用的是子對象,因此,在執行持久化操作的時候,需要根據參數進行額外的處理。默認情況下,當持久化實體對象的時候,SubObjectAttribute指示的屬性,不進行操作。
這個類的定義如下:
[AttributeUsage(AttributeTargets.Property)] public class SubObjectAttribute : Attribute { private Type subObjectType; private string primaryKey; private string foreignKey; public SubObjectAttribute(Type subObjectType, string primaryKey, string foreignKey) { this.subObjectType = subObjectType; this.primaryKey = primaryKey; this.foreignKey = foreignKey; } public SubObjectAttribute(){} public Type SubObjectType { get { return subObjectType; } set { subObjectType = value; } } public string PrimaryKey { get{return primaryKey;} set{primaryKey = value;} } public string ForeignKey { get{return foreignKey;} set{foreignKey = value;} } } |
Ø AutoIncreaseAttribute
AutoIncreaseAttribute指示該屬性是自動增長的。自動增長默認種子爲1。需要指出的是,自動增長的屬性只適用於MS SqlServer,Websharp目前不支持其他數據庫的自動增長列。
這個類的定義如下:
[AttributeUsage(AttributeTargets.Property)] public class AutoIncreaseAttribute : Attribute { private int step = 1; public AutoIncreaseAttribute(){} public AutoIncreaseAttribute(int step) { this.step = step; } public int Step { get{return step;} set{step = value;} } } |
設計好映射的方法後,我們就可以來定義實體類以及同數據庫之間的映射。下面是一個例子:
//訂單類別 [TableMap("OrderType","ID")] public class OrderType { private int m_ID; private string m_Name; [ColumnMap("ID",DbType.Int32)] public int ID { get { return m_ID; } set { m_ID = value; } } [ColumnMap("Name", DbType.String)] public string Name { get { return m_Name; } set { m_Name = value; } } } //訂單 [TableMap("PurchaseOrder", "OrderID")] public class Order { private int m_OrderID; private OrderType m_OrderType; private string m_Title; private DateTime m_AddTime; private bool m_IsSigned; private List<OrderDetail> m_Details; [ColumnMap("OrderID",DbType.Int32)] [AutoIncrease] public int OrderID { get { return m_OrderID; } set { m_OrderID = value; } } [ReferenceObject(typeof(OrderType),"ID","TypeID")] [ColumnMap("TypeID",DbType.String)] public OrderType OrderType { get { return m_OrderType; } set { m_OrderType = value; } } [ColumnMap("Title", DbType.String)] public string Title { get { return m_Title; } set { m_Title = value; } } [ColumnMap("AddTime", DbType.DateTime)] public DateTime AddTime { get { return m_AddTime; } set { m_AddTime = value; } } [ColumnMap("AddTime", DbType.Boolean)] public bool IsDigned { get { return m_IsSigned; } set { m_IsSigned = value; } } [SubObject(typeof(OrderDetail),"OrderID","OrderID")] public List<OrderDetail> Details { get { return m_Details; } set { m_Details = value; } } } //訂單明細 public class OrderDetail { private int m_DetailID; private int m_OrderID; private string m_ProductName; private int m_Amount; [ColumnMap("ID", DbType.Int32)] [AutoIncrease] public int DetailID { get { return m_DetailID; } set { m_DetailID = value; } } [ColumnMap("OrderID", DbType.Int32)] public int OrderID { get { return m_OrderID; } set { m_OrderID = value; } } [ColumnMap("ProductName", DbType.String)] public string ProductName { get { return m_ProductName; } set { m_ProductName = value; } } [ColumnMap("Amount", DbType.Int32)] public int Amount { get { return m_Amount; } set { m_Amount = value; } } } |
Order中
[ReferenceObject(typeof(OrderType),"ID","TypeID")] [ColumnMap("TypeID",DbType.String)] public OrderType OrderType { get { return m_OrderType; } set { m_OrderType = value; } } |
這段代碼表明,OrderType這個屬性,引用了OrderType這個對象,同OrderType相關聯的,是OrderType的主鍵ID和Order的外鍵TypeID。
[SubObject(typeof(OrderDetail),"OrderID","OrderID")] public List<OrderDetail> Details { get { return m_Details; } set { m_Details = value; } } |
這段代碼表明,Details這個屬性,由子對象OrderDetail的集合組成,其中,兩個對象通過Order類的OrderID主鍵和OrderDetail的外鍵OrderID相關聯。
四. 對繼承的支持
Websharp框架在設計的時候,要求能夠支持面嚮對象語言中的繼承。Websharp支持三種繼承模式:ONE_INHERITANCE_TREE_ONE_TABLE、ONE_INHERITANCE_PATH_ONE_TABLE和ONE_CLASS_ONE_TABLE。以如下的類結構爲例:
ONE_INHERITANCE_TREE_ONE_TABLE
這種映射模式將具有相同父類的所有類都映射到一個數據庫表中。數據庫結構如下圖:
在Websharp中,只需要對每個類都指明具有相同值的TableMap特性就可以了。如下面的代碼:
[TableMap("Table1", "Property1")] public class Parent { private string property1; private string property2; [ColumnMap("Column1", DbType.String)] public string Property1 { get { return property1; } set { property1=value; } } [ColumnMap("Column2", DbType.String)] public string Property2 { get { return property2; } set { property2 = value; } } } [TableMap("Table1", "Property1")] public class Child1 : Parent { private string property3; [ColumnMap("Column3", DbType.String)] public string Property3 { get { return property3; } set { property3 = value; } } } [TableMap("Table1", "Property1")] public class Child2 : Parent { private string property4; [ColumnMap("Column4", DbType.String)] public string Property4 { get { return property4; } set { property4 = value; } } } |
此時,當按照如下的代碼初始化一個Child1對象,
Child c1.Property1 = "P11"; c1.Property2 = "P12"; c1.Property3 = "P13"; |
並保存到數據庫中的時候,數據庫中的記錄應該是:
Column1 |
Column2 |
Column3 |
Column4 |
P11 |
P12 |
P13 |
NULL |
如果按照如下的代碼初始化一個Child2對象:
Child c2.Property1 = "P21"; c2.Property2 = "P22"; c2.Property4 = "P24"; |
並保存到數據庫中的時候,數據庫中的記錄應該是:
Column1 |
Column2 |
Column3 |
Column4 |
P21 |
P22 |
NULL |
P24 |
ONE_INHERITANCE_PATH_ONE_TABLE
這種映射模式將一個繼承路徑映射到一個表,這種情況下的數據庫的結構是:
這種情況下,實際上Parent類並不映射到實際的表,Child1和Child2類分別映射到Child1和Child2表。因此,在這種情況下,需要把Parent類的TableMap特性設置爲Null,而Child1和Child2類的TableMap特性分別設置爲Child1和Child2,代碼如下面所示:
[TableMap(null, "Property1")] public class Parent { private string property1; private string property2; [ColumnMap("Column1", DbType.String)] public string Property1 { get { return property1; } set { property1=value; } } [ColumnMap("Column2", DbType.String)] public string Property2 { get { return property2; } set { property2 = value; } } } [TableMap("Child1", "Property1")] public class Child1 : Parent { private string property3; [ColumnMap("Column3", DbType.String)] public string Property3 { get { return property3; } set { property3 = value; } } } [TableMap("Child2", "Property1")] public class Child2 : Parent { private string property4; [ColumnMap("Column4", DbType.String)] public string Property4 { get { return property4; } set { property4 = value; } } } |
此時,當按照如下的代碼初始化一個Child1對象,
Child c1.Property1 = "P11"; c1.Property2 = "P12"; c1.Property3 = "P13"; |
並保存到數據庫中的時候,數據庫中應該只在Child1表中添加下面的數據:
Column1 |
Column2 |
Column3 |
P11 |
P12 |
P13 |
如果保存的是一個Child2對象,那麼,應該只在Child2表中添加數據。Child1表和Child2表是互相獨立的,並不會互相影響。
ONE_CLASS_ONE_TABLE
這種映射模式將每個類映射到對應的一個表,對於上面的類結構,數據庫的結構是:
這種映射模式,我們只需要分別對每個類設定各自映射的表就可以了。代碼如下面所示:
[TableMap("Parent", "Property1")] public class Parent { private string property1; private string property2; [ColumnMap("Column1", DbType.String)] public string Property1 { get { return property1; } set { property1=value; } } [ColumnMap("Column2", DbType.String)] public string Property2 { get { return property2; } set { property2 = value; } } } [TableMap("Child1", "Property1")] public class Child1 : Parent { private string property3; [ColumnMap("Column3", DbType.String)] public string Property3 { get { return property3; } set { property3 = value; } } } [TableMap("Child2", "Property1")] public class Child2 : Parent { private string property4; [ColumnMap("Column4", DbType.String)] public string Property4 { get { return property4; } set { property4 = value; } } } |
此時,當按照如下的代碼初始化一個Child1對象,
Child c1.Property1 = "P11"; c1.Property2 = "P12"; c1.Property3 = "P13"; |
並保存到數據庫中的時候,數據庫中的記錄應該是:
Parent表:
Column1 |
Column2 |
P11 |
P12 |
Child1表:
Column1 |
Column3 |
P11 |
P13 |
同樣的,如果保存的是一個Child2對象,那麼,將在Parent表和Child2表中添加記錄。
五. PersistenceManager
Websharp O/R Mapping框架的操作核心,在於PersistenceManager接口,對實體對象的操作,包括增、刪、改的操作,都是通過這個接口來進行的。
PersistenceManager的定義如下:
/** * 這個接口定義持久化操作的方法 * */ public interface PersistenceManager : IDisposable { /* * 關閉一個PersistenceManager。當一個PersistenceManager被關閉的時候,需要做如下的工作 * 1、釋放它所管理的實體類,以及相關的狀態。如果不釋放,可能造成內存泄露 * 2、如果Flush方法沒有被執行,則執行Flush方法。 * 3、釋放數據庫聯接等資源。 * 4、從PersistenManagerfactroy中清除自己 */ void Close(); /** * 判斷一個PersistenceManager是否已經關閉了。 */ bool IsClosed{get;} /** * 獲取PersistenceManager當前所處的事務 */ Transaction CurrentTransaction{ get;} /** * 指示在默認的情況下,所有的操作是否忽略緩存。如果忽略緩存,那麼,有的時候會存在一些不一致的情況,除非系統被禁止了緩存的使用 */ bool IgnoreCache{get;set;} /** * 將一個新的實體對象轉換成可持續對象,這個對象在事務結束的時候,會被Insert到數據庫中 * 調用這個方法後,該對象的狀態爲EntityState.New * 如果一個對象的狀態爲EntityState.Persistent,則本方法將拋出一個EntityIsPersistentException異常 */ void PersistNew(object entity); void PersistNew(object entity,PersistOptions options); /* * 將一個新的實體對象轉換成可持續對象,並且指明要保存的屬性 * */ void PersistNew(object entity, params string[] properties); void PersistNew(object entity, PersistOptions options, params string[] properties); /** * 將一個實體對象保存到數據庫中。 * 如果一個對象是Trasient的,則將其轉換爲EntityState.New狀態。在事務結束的時候,會被Insert到數據庫中 * 否則,其狀態就是EntityState.Persist,就更新到數據庫中。 * 如果一個Trasient對象實際上已經存在於數據庫中,由於Persist方法並不檢查實際的數據庫,因此, * 調用這個方法,將會拋出異常。這個時候,應該使用先使用Attach方法,然後調用Persist。 * Persist方法主要用於已受管的對象的更新 */ void Persist(object entity); void Persist(object entity,PersistOptions options); /** * 將一個實體對象保存到數據庫中,並且指明要保存的屬性 * */ void Persist(object entity,params string[] properties); void Persist(object entity,PersistOptions options,params string[] properties); /** * 強制將一個實體更新到數據庫中。 * 執行這個方法,將把對象的狀態強制變爲EntityState.Persist。 * 由於Update方法並不檢查實際的數據庫,因此如果一個對象實際上不存在於數據庫中,那麼,這個方法實際上 * 不會對數據庫造成變化。 * 如果不能確認對象已經存在於數據庫中,那麼,應該使用先使用Attach方法。 */ void Update(object entity); void Update(object entity, PersistOptions options); /** * 將一個實體對象更新到數據庫中,並且指明要保存的屬性 * */ void Update(object entity, params string[] properties); void Update(object entity, PersistOptions options, params string[] properties); /** * 刪除一個對象。 * 一個對象被刪除後,其狀態變成EntityState.Deleted,在事務結束的時候,會被從數據庫中刪除。 * 如果一個對象不是持久的,那麼,這個方法將拋出異常。 * */ void Delete(object entity); void Delete(object entity,PersistOptions options); /** * 將一個對象標記爲可持續的。如果這個對象已經存在於實際的數據庫中,那麼,這個對象的狀態就是 * EntityState.Persistent,否則,這個對象的狀態就是EntityState.New。 * 注意:這個方法不會導致對數據庫實際數據的更改 */ void Attach(object entity); void Attach(object entity,PersistOptions options); /** * 重新從數據庫中載入這個對象,這意味着重新給對象的各個屬性賦值。 * */ void Reload(ref object entity); void Reload(ref object entity,PersistOptions options); /** * 從緩存中把某個對象移除。 * */ void Evict (object entity); void EvictAll (object[] pcs); void EvictAll (IEnumerable pcs); void EvictAll (); /** * 根據主鍵查找某個對象,如果主鍵是多個字段的,順序必須同TableMapAttribute中的順序相同,否則將有不可預測的事情發生 */ object FindByPrimaryKey(Type entityType,params object[] id); object FindByPrimaryKey(Type entityType, PersistOptions options, params object[] id); T FindByPrimaryKey<T>(params object[] id); T FindByPrimaryKey<T>(PersistOptions options, params object[] id); /** *獲取某個對象的狀態。這個對象必須是受該PersistenceManager管理的,否則,拋出異常 */ EntityState GetState(object entity); ICollection GetManagedEntities(); /** * 本操作使對實體對象所作的更改立即生效。 */ bool Flush(); /// <summary> /// 該方法撤銷前面所做的所有操作。 /// </summary> void Cancel(); /** * 創建Query對象。 * */ Query NewQuery(); Query NewQuery(Type entityType); Query NewQuery(Type entityType,string filter); Query NewQuery(Type entityType,string filter,QueryParameterCollection paramColletion); Query<T> NewQuery<T>(); Query<T> NewQuery<T>(string filter); Query<T> NewQuery<T>(string filter, QueryParameterCollection paramColletion); } |
PersistenceManager接口的相應的方法的說明已經在上面列出了,也是一目瞭然的。額外需要說明的是,這些對對象的操縱,都是暫存在內存中,只有在調用了Flush方法後才生效,纔會把對數據的改變保存到數據庫中。調用Cancel方法,可以撤銷這些操作。
六. 事務處理
Websharp框架提供了簡單的事務處理的能力,這是通過Transaction接口來實現的。
Transaction接口的定義如下:
public interface Transaction { void Begin(); void Commit(); void Rollback(); PersistenceManager PersistenceManager{get;} } |
這個接口定義的非常簡單,就是提供了開始事務、提交或者回滾事務的方法。下面的例子說明了在Websharp裏面如何使用事務:
public void TransactionTest() { //設定環境 DatabaseProperty dbp = new DatabaseProperty(); dbp.DatabaseType = DatabaseType.MSSQLServer; dbp.ConnectionString = "Data Source=(local);Initial Catalog=WebsharpTest;Integrated Security=True"; //操作數據 PersistenceManager pm = PersistenceManagerFactory.Instance().Create(dbp); Product p0 = new Product("Name0", 100); pm.PersistNew(p0); Product p1 = new Product("Name1", 101); pm.PersistNew(p1); Transaction t = pm.CurrentTransaction; //獲取當前事務對象 t.Begin(); //開始事務 pm.Flush(); t.Commit(); //提交事務 pm.Close(); } |
七. 對象查詢
Websharp框架通過Query接口,提供對象查詢的功能。Query接口的定義如下:
public interface Query { Type EntityType{get;set;} string EntityTypeName{get;set;} string Filter{get;set;}
QueryParameterCollection Parameters{get;set;} string Ordering{get;set;}
bool IgnoreCache{get;set;} ICollection QueryObjects(); DataSet QueryDataSet(); PersistenceManager PersistenceManager{get;} bool IsClosed{get;} void Close(); //void Open(); } |
同時,Websharp提供了一個範型的版本,定義如下:
public interface Query<T> : Query { new ICollection<T> QueryObjects(); } |
使用Query的一般步驟是:
1、 從PersistenceManager獲得一個Query接口
2、 設定Query接口要查詢的類型、條件(Filter)和相應的參數
3、 執行QueryObjects方法,得到相應的對象集合。
下面的例子說明了使用Query的過程:
public void NormalQuery() { DatabaseProperty dbp = new DatabaseProperty(); dbp.DatabaseType = DatabaseType.Oracle; dbp.ConnectionString = "Data Source=ORACLE1453;User Id=websharp;Password=websharp"; ApplicationConfiguration.FrameworkUssage = FrameworkUssage.Normal; ApplicationConfiguration.DefaultDatabaseProperty = dbp; PersistenceManager pm = PersistenceManagerFactory.Instance().Create(); Query<Pencil> q = pm.NewQuery<Pencil>(); q.Filter = "Owner like :Owner"; QueryParameterCollection qpm = new QueryParameterCollection(1); QueryParameter qm = new QueryParameter(":Owner", "sunny"); qpm.Add(qm); q.Parameters = qpm; ICollection<Pencil> pencils = q.QueryObjects(); pm.Close(); } |
八. 配置文件
配置文件配置了Websharp運行時需要的一些信息,目前來說,在O/R Mapping部分,需要配置的是關於緩存的信息。在緩存部分,Websharp使用了微軟的Enterprise工具中的緩存部分,因此,需要配置的信息同微軟的Enterprise工具中的緩存部分一樣。所需要添加的,就是緩存過期的策略部分,這個部分,在WebsharpExpirationPolicy中進行說明。配置文件的內容如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings,
Microsoft.Practices.EnterpriseLibrary.Caching, Version= <section name="WebsharpExpirationPolicy" type="Websharp.ORM.Service.WebsharpCofigurationHandler,Websharp.ORM.Service" /> </configSections> <cachingConfiguration defaultCacheManager="Cache Manager"> <cacheManagers> <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="Null Storage" name="Cache Manager" /> <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="Null Storage" name="EntityCache" /> <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000" numberToRemoveWhenScavenging="10" backingStoreName="Null Storage" name="SqlCache" /> </cacheManagers> <backingStores> <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore,
Microsoft.Practices.EnterpriseLibrary.Caching, Version= name="Null Storage" /> </backingStores> </cachingConfiguration> <WebsharpExpirationPolicy> <ExpirationPolicy ExpirationCheckInterval="60" AssemblyName="Microsoft.ApplicationBlocks.Cache" ClassName="Microsoft.ApplicationBlocks.Cache.ExpirationsImplementations.SlidingTime" /> </WebsharpExpirationPolicy> </configuration> |
Websharp默認使用的是時間過期清除緩存的策略,過期的時間,可以修改,單位爲秒。
原文引用地址