程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> LINQ to SQL實現數據訪問通用基類(續)

LINQ to SQL實現數據訪問通用基類(續)

編輯:關於.NET

在我們基於Domain驅動模式開發面向對象的多層架構的時候,層和層之間數據的傳輸對象(DTO)往往 簡化為領域對象模型,在上文中就是我們利用LINQ TO SQL對象設計器生成的Bill,Customer等實體類。

存在的問題

通常的做法,我們把這些實體類單獨分成一層,這樣程序分層劃分成如下:

數據訪問層(Data Access Layer)

業務層 (Business Layer)

用戶界面層(UI Layer)

實體層(Entity Layer)

注意,多層應用程序,一般遵守這樣的規則:UI調用BL,BL調用DL,不能跨級調用,也不能底層調用 上層,但是實體層是我們的DTO,各個層都可以調用它。

如果這樣劃分,我們系統就出現問題:

我們把RepositoryBase劃到數據層,LINQ TO SQL對象設計器生成的類分到實體層,數據層引用實體層 ,沒有問題,但是我們看到,在我們實體層,存在一個方法(以Bill為例):

public static RepositoryBase<Bill, LINQtoSQLHelper.DataContextSetUp> CreateRepository() { return new BillRepository(); }

數據層也必須引用數據訪問層,循環引用。另外,對於如何體現loadoption那?

解決循環引用

以Bill實體為例,循環引用的病因在於Bill實體中添加這樣一個方法:

public static RepositoryBase<Bill, LINQtoSQLHelper.DataContextSetUp> CreateRepository() { return new BillRepository(); }

為什麼要添加這個方法那?這樣做就是充血模式的實體了。注意到RepositoryBase.cs有一段代碼:

try
{
    object Repository = association.OtherType.Type.GetMethod("CreateRepository").Invoke (null, null);
    Repository.GetType().GetMethod("IterateEntitySet",
                                 BindingFlags.NonPublic | BindingFlags.Instance).Invoke(
        Repository,
        new object[4]
        {
            AssociationProperty.GetValue(theEntity, null),
            context,
            OperationMode,
            Recursively
        }
        );
}
catch (System.Reflection.TargetInvocationException e)
{
    throw (e.InnerException);
}

作者添加這段代碼,主要是利用反射獲取當前實體的CreateRepository方法,實現對象的CRUD操作。 如果實體中去掉這個CreateRepository方法,那這段代碼如何變通,請看:

dd

try

                            {

                                object Repository = association.OtherType.Type.GetMethod("CreateRepository").Invoke(null, null);

                                 Repository.GetType().GetMethod ("IterateEntitySet",

                                                              BindingFlags.NonPublic | BindingFlags.Instance).Invoke(

                                     Repository,

                                     new object[4]

                                     {

                                         AssociationProperty.GetValue(theEntity, null),

                                         context,

                                         OperationMode,

                                         Recursively

                                     }

                                     );

                             }

                            catch (System.Reflection.TargetInvocationException e)

                             {

                                 throw (e.InnerException);

                            }

主要利用反射,從當前數據訪問層Assembly中獲得對應實體類的的Repository類。

好,解決循環引用問題。

體現loadoption

這個問題比較棘手,確實在底層無法感知業務需求的東西,而其DataContext是共用的。

能不能另辟捷徑那?注意我們用泛型構造RepositoryBase類,那能不能從中得到什麼那?

我們對類RepositoryBase添加入如下方法:

        public IList<TEntityType> Where(string predicate, params object[] values)

        {

            InitDataContext ();

            return m_context.GetTable<TEntityType>().Where (predicate, values).ToList<TEntityType>();

        }

         public IList<TEntityType> OrderBy(string ordering, params object[] values)

        {

            InitDataContext();

             return m_context.GetTable<TEntityType>().OrderBy(ordering, values).ToList<TEntityType>();

        }

        public IList<TEntityType> Take(int count)

        {

             InitDataContext();

            return m_context.GetTable<TEntityType>().Take<TEntityType> (count).ToList<TEntityType>();

        }

        public IQueryable Select(string selector, params object[] values)

        {

             InitDataContext();

            return m_context.GetTable<TEntityType>().Select(selector, values);

        }

        #endregion

        #region Query Methods (Lambda Expression)

        public IList<TEntityType> Where(Func<TEntityType, bool> predicate)

        {

            InitDataContext ();

            return m_context.GetTable<TEntityType>().Where (predicate).ToList<TEntityType>();

        }

好,這個基本上體現loadoption。

反饋!

本文是對我翻譯上一篇文章的一個補從,代碼你可以自由使用,但是必須聲明出處。

本文配套源碼:http://www.bianceng.net/dotnet/201212/726.htm

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved