新版Websharp使用說明(適合於.Net2005)

一.     前言

Websharp的目標,是開發一個開源的基於Microsoft.Net的輕量級的應用軟件系統開發框架,包含以下內容:

Ø         一個輕量級的O/R Mapping框架

Ø         一個輕量級的AOP框架

Ø         一個輕量級的ServiceLocator,主要目的是爲整合不同服務端技術的客戶端編程。

二.     Websharp O/R Mapping起步

Websharp ORM是一個輕量級的O/R Mapping框架,主要特點是拋棄了Java中常見的,也是其他一些O/R Mapping產品中使用XML文件來做映射描述的方法,而使用Attribute作爲描述映射的方法,簡單明瞭,並且,對開發人員來說,只有PersistenceManagerQueryTransaction等極少數接口需要掌握,上手快,使用非常方便。

因爲在某些地方使用了範型,所以目前版本的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 Main(string[] args)

{

         //設定環境

    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=2.0.0.0, Culture=neutral, PublicKeyToken=null" />

    <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=2.0.0.0, Culture=neutral, PublicKeyToken=null"

        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指明所引用的對象的類型,PrimaryKeyForeignKey用來指明兩個類之間進行關聯的主鍵和外鍵。這個類的定義如下:

         [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 SqlServerWebsharp目前不支持其他數據庫的自動增長列。

這個類的定義如下:

         [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的主鍵IDOrder的外鍵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_TABLEONE_INHERITANCE_PATH_ONE_TABLEONE_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對象,

    Child1 c1 = new Child1();

    c1.Property1 = "P11";

    c1.Property2 = "P12";

    c1.Property3 = "P13";

並保存到數據庫中的時候,數據庫中的記錄應該是:

Column1

Column2

Column3

Column4

P11

P12

P13

NULL

如果按照如下的代碼初始化一個Child2對象:

    Child2 c1 = new Child2();

    c2.Property1 = "P21";

    c2.Property2 = "P22";

    c2.Property4 = "P24";

並保存到數據庫中的時候,數據庫中的記錄應該是:

Column1

Column2

Column3

Column4

P21

P22

NULL

P24

 

ONE_INHERITANCE_PATH_ONE_TABLE

這種映射模式將一個繼承路徑映射到一個表,這種情況下的數據庫的結構是:


    這種情況下,實際上
Parent類並不映射到實際的表,Child1Child2類分別映射到Child1Child2表。因此,在這種情況下,需要把Parent類的TableMap特性設置爲Null,而Child1Child2類的TableMap特性分別設置爲Child1Child2,代碼如下面所示:

    [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對象,

    Child1 c1 = new Child1();

    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對象,

    Child1 c1 = new Child1();

    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=2.0.0.0, Culture=neutral, PublicKeyToken=null" />

    <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=2.0.0.0, Culture=neutral, PublicKeyToken=null"

        name="Null Storage" />

    </backingStores>

  </cachingConfiguration>

 

  <WebsharpExpirationPolicy>

    <ExpirationPolicy ExpirationCheckInterval="60" AssemblyName="Microsoft.ApplicationBlocks.Cache" ClassName="Microsoft.ApplicationBlocks.Cache.ExpirationsImplementations.SlidingTime" />

  </WebsharpExpirationPolicy>

</configuration>

Websharp默認使用的是時間過期清除緩存的策略,過期的時間,可以修改,單位爲秒。


  原文引用地址
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章