zoukankan      html  css  js  c++  java
  • 新的IRepository接口+搜索和排序解耦(+基于Castle实现)

    新的IRepository接口+搜索和排序解耦(+基于Castle实现)

    经过了上篇IRepositoryIRepository<T>的讨论【文章地址为:http://www.cnblogs.com/yomho/p/3296759.html

    我选择了IRepository作为我重构框架的仓储接口

    一、接口定义                                                 

    新的IRepository接口设计如下:

    复制代码
     1 namespace Yom.NFramework2_0
     2 {
     3     public interface IRepository<TCompositeKey>
     4         where TCompositeKey : IEquatable<string>
     5     {
     6         #region 实体操作接口
     7         T FindBy<T>(TCompositeKey primaryKey) where T : IEntity;
     8         IEnumerable<T> FindAll<T>() where T : IEntity;
     9         IEnumerable<T> FindAll<T>(IWhere[] where) where T : IEntity;
    10         IEnumerable<T> FindAll<T>(IWhere[] where, IOrder[] order) where T : IEntity;
    11         IEnumerable<T> FindAll<T>(int pageIndex, int pageSize, IWhere[] where, IOrder[] order, out int count) where T : IEntity;
    12         void Add<T>(T entity) where T : IEntity;
    13         void Delete<T>(T entity) where T : IEntity;
    14         void DeleteAll<T>() where T : IEntity;
    15         void DeleteAll<T>(IWhere[] where) where T : IEntity;
    16         void DeleteAll<T>(string where) where T : IEntity;
    17         void DeleteAll<T>(IEnumerable<TCompositeKey> pkValues) where T : IEntity;
    18         void Update<T>(T entity) where T : IEntity;
    19         bool Exists<T>(TCompositeKey primaryKey) where T : IEntity;
    20         #endregion
    21         #region 静态方法接口
    22         int ExecuteSql(string sql, params System.Data.IDataParameter[] ps);
    23         object ExecuteScalar(string sql, params System.Data.IDataParameter[] ps);
    24         System.Data.DataTable ExecuteDataTable(string sql, params System.Data.IDataParameter[] ps);
    25         #endregion
    26     }
    27 }
    复制代码

    其中IEntity和IWhere以及IOrder的设计接口如下:

    复制代码
    public interface IEntity
        {
        }
    public interface IOrder
        {
        }
    public interface IWhere
        {
        }
    public interface ICompositeKey : IEquatable<string>
        {
        }
    复制代码

    ICompositeKey为组合主键接口

    为什么ICompositeKey要继承为IEquatable<string>这个接口呢?

    因为IEquatable<string>是string的基类,且string为不能继承的类,

    所以目的是和string兼容,经过处理可以变成一个string类,从而可以兼容普通的非组合主键。

    (此文不讲组合主键的实现原理,展示组合主键接口只是让大家看看组合主键实现解耦的方法)

    二、嫁接Castle实现搜索以及排序                                   

    很多人不知道怎么把自己的IRepository接口的排序和搜索对象解耦,

    在用不同的ORM实现IRepository接口的时候总不知道怎么弄排序和搜索

    下面就来看我怎么把Castle的排序和搜索用IOrder以及IWhere解耦的

    首先是IOrder -> NHibernate.Expression.Order 的变身

    复制代码
    1 namespace Yom.NFramework2_0.CastleExtend
    2 {
    3     public class OrderBase : NHibernate.Expression.Order, Yom.NFramework2_0.IOrder
    4     {
    5         public OrderBase(string propertyName, bool ascending) : base(propertyName, ascending) { 
    6         
    7         }
    8     }
    9 }
    复制代码

    这个很简单,OrderBase一下子就变成了NHibernate.Expression.Order

    那么IWhere是否可以顺利完成像IOrder这种变身么?

    研究后发现:Castle是用NHibernate.Expression.Expression的静态方法创建查询对象的

    静态方法都是返回NHibernate.Expression.AbstractCriterion抽象类或者ICriterion接口

    可以继承这个抽象对象或者接口吧,这样就可以实现变身了!!!

    但如果真要这样做,必然有抽象方法要实现,这实在是一个下下策(想嫁接个接口和抽象类不容易吖)

    那有没有直接实现NHibernate.Expression.AbstractCriterion抽象类的类呢?

    反正我是没有找到,但是Castle肯定有,如果找到这么个类,就可以像IOrder一样实现嫁接,现在没有发现只能想他法。

    最后我对WhereBase的变身是:

    复制代码
      1 namespace Yom.NFramework2_0.CastleExtend
      2 {
      3     public class WhereBase : Yom.NFramework2_0.IWhere
      4     {
      5         public NHibernate.Expression.ICriterion Instance
      6         {
      7             get;
      8             set;
      9         }
     10         public override string ToString()
     11         {
     12             return Instance.ToString();
     13         }
     14         #region 废弃代码
     15         //public static void AllEq(WhereBase where, System.Collections.IDictionary propertyNameValues)
     16         //{
     17         //    where.Instance = NHibernate.Expression.Expression.AllEq(propertyNameValues);
     18         //}
     19         //public static void And(WhereBase where, WhereBase whereA, WhereBase whereB)
     20         //{
     21         //    where.Instance = NHibernate.Expression.Expression.And(whereA.Instance, whereB.Instance);
     22         //}
     23         //public static void Between(WhereBase where, string propertyName, object lo, object hi)
     24         //{
     25         //    where.Instance = NHibernate.Expression.Expression.Between(propertyName, lo, hi);
     26         //}
     27         //public static void Eq(WhereBase where, string propertyName, object value) {
     28         //    where.Instance = NHibernate.Expression.Expression.Eq(propertyName, value);
     29         //}
     30         //public static void EqProperty(WhereBase where, string propertyName, string otherPropertyName)
     31         //{
     32         //    where.Instance = NHibernate.Expression.Expression.EqProperty(propertyName, otherPropertyName);
     33         //}
     34         //public static void Ge(WhereBase where, string propertyName, object value)
     35         //{
     36         //    where.Instance = NHibernate.Expression.Expression.Ge(propertyName, value);
     37         //}
     38         //public static void GeProperty(WhereBase where, string propertyName, string otherPropertyName)
     39         //{
     40         //    where.Instance = NHibernate.Expression.Expression.GeProperty(propertyName, otherPropertyName);
     41         //}
     42         //public static void Gt(WhereBase where, string propertyName, object value)
     43         //{
     44         //    where.Instance = NHibernate.Expression.Expression.Gt(propertyName, value);
     45         //}
     46         //public static void GtProperty(WhereBase where, string propertyName, string otherPropertyName)
     47         //{
     48         //    where.Instance = NHibernate.Expression.Expression.GtProperty(propertyName, otherPropertyName);
     49         //}
     50         //public static void IdEq(WhereBase where, object value)
     51         //{
     52         //    where.Instance = NHibernate.Expression.Expression.IdEq(value);
     53         //}
     54         //public static void In(WhereBase where, string propertyName, System.Collections.ICollection values)
     55         //{
     56         //    where.Instance = NHibernate.Expression.Expression.In(propertyName, values);
     57         //}
     58         //public static void InG<T>(WhereBase where, string propertyName, ICollection<T> values)
     59         //{
     60         //    where.Instance = NHibernate.Expression.Expression.InG<T>(propertyName, values);
     61         //}
     62         //public static void InsensitiveLike(WhereBase where, string propertyName, object value)
     63         //{
     64         //    where.Instance = NHibernate.Expression.Expression.InsensitiveLike(propertyName, value);
     65         //}
     66         //public static void IsEmpty(WhereBase where, string propertyName)
     67         //{
     68         //    where.Instance = NHibernate.Expression.Expression.IsEmpty(propertyName);
     69         //}
     70         //public static void propertyName(WhereBase where, string propertyName)
     71         //{
     72         //    where.Instance = NHibernate.Expression.Expression.IsNotEmpty(propertyName);
     73         //}
     74         //public static void IsNotNull(WhereBase where, string propertyName)
     75         //{
     76         //    where.Instance = NHibernate.Expression.Expression.IsNotNull(propertyName);
     77         //}
     78         //public static void IsNull(WhereBase where, string propertyName)
     79         //{
     80         //    where.Instance = NHibernate.Expression.Expression.IsNull(propertyName);
     81         //}
     82         //public static void Le(WhereBase where, string propertyName, object value)
     83         //{
     84         //    where.Instance = NHibernate.Expression.Expression.Le(propertyName, value);
     85         //}
     86         //public static void LeProperty(WhereBase where, string propertyName, string otherPropertyName)
     87         //{
     88         //    where.Instance = NHibernate.Expression.Expression.LeProperty(propertyName, otherPropertyName);
     89         //}
     90         //public static void Like(WhereBase where, string propertyName, string value, NHibernate.Expression.MatchMode matchModes)
     91         //{
     92         //    where.Instance = NHibernate.Expression.Expression.Like(propertyName, value, matchModes);
     93         //}
     94 
     95         //public static void Lt(WhereBase where, string propertyName, object value)
     96         //{
     97         //    where.Instance = NHibernate.Expression.Expression.Lt(propertyName, value);
     98         //}
     99         //public static void LtProperty(WhereBase where, string propertyName, string otherPropertyName)
    100         //{
    101         //    where.Instance = NHibernate.Expression.Expression.LtProperty(propertyName, otherPropertyName);
    102         //}
    103         //public static void Not(WhereBase where)
    104         //{
    105         //    where.Instance = NHibernate.Expression.Expression.Not(where.Instance);
    106         //}
    107         //public static void NotEqProperty(WhereBase where, string propertyName, string otherPropertyName)
    108         //{
    109         //    where.Instance = NHibernate.Expression.Expression.NotEqProperty(propertyName, otherPropertyName);
    110         //}
    111         //public static void Or(WhereBase where, WhereBase whereA, WhereBase whereB)
    112         //{
    113         //    where.Instance = NHibernate.Expression.Expression.Or(whereA.Instance, whereB.Instance);
    114         //}
    115         //public static void Sql(WhereBase where, string sql)
    116         //{
    117         //    where.Instance = NHibernate.Expression.Expression.Sql(sql);
    118         //}
    119         #endregion
    120     }
    121 }
    复制代码

    最好注释也去掉,这样的好处是别人开发的可以不管ORM是用什么第三方框架,直接调用WhereBase静态方法(代理模式)

    WhereBase直接携带了Castle的搜索接口ICriterion,

    在RepositoryBase有个这么个方法转换IWhere为Castle的搜索对象

    复制代码
     1 #region 其他方法
     2         NHibernate.Expression.ICriterion[] IWhere2ICriterion(IWhere[] where)
     3         {
     4             if (where == null) {
     5                 return null;
     6             }
     7             NHibernate.Expression.ICriterion[] wheres = new NHibernate.Expression.ICriterion[where.Length];
     8             for (var i = 0; i < where.Length; i++)
     9             {
    10                 wheres[i] = (where[i] as WhereBase).Instance;
    11             }
    12             return wheres;
    13         }
    14         #endregion
    复制代码

    这样就可以完美地实现搜索和排序的解耦

    仓储基类有个方法实现如下:

    复制代码
    1 public IEnumerable<T> FindAll<T>(IWhere[] where) where T : IEntity
    2         {
    3             if (where == null) {
    4                 return FindAll<T>();
    5             }
    6             return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(IWhere2ICriterion(where));
    7         }
    复制代码

    三、总结:                                                                                 

    1:搜索和排序的解耦不算是个难题

    2: 实现的仓储基类可以通过IoC注入实例化,这样可以插拔式更换ORM

    3: 定义的仓储接口和实现最好放在不同的类库,以更好的解耦

    四、后记:Repository实现仓储--Castle实现                                                 

    1 namespace Yom.NFramework2_0.CastleExtend
    2 {
    3     public abstract class EntityBase : Castle.ActiveRecord.ActiveRecordBase, Yom.NFramework2_0.IEntity
    4     {
    5     }
    6 }

    实体基类嫁接

    1 namespace Yom.NFramework2_0
    2 {
    3     public interface ISinglePrimaryKeyRepository : IRepository<string>
    4     {
    5     }
    6 }


    非组合主键仓储扩展

    复制代码
      1 namespace Yom.NFramework2_0.CastleExtend
      2 {
      3     public class CastleSinglePrimaryKeyRepository : ISinglePrimaryKeyRepository//, System.Configuration.IConfigurationSectionHandler
      4     {
      5         #region IRepository<string> 成员
      6 
      7         #region 实体相关操作
      8         public T FindBy<T>(string primaryKey) where T : IEntity
      9         {
     10             return Castle.ActiveRecord.ActiveRecordBase<T>.Find(primaryKey);
     11         }
     12 
     13         public IEnumerable<T> FindAll<T>() where T : IEntity
     14         {
     15             return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll();
     16         }
     17 
     18         public IEnumerable<T> FindAll<T>(IWhere[] where) where T : IEntity
     19         {
     20             if (where == null) {
     21                 return FindAll<T>();
     22             }
     23             return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(IWhere2ICriterion(where));
     24         }
     25 
     26         public IEnumerable<T> FindAll<T>(IWhere[] where, IOrder[] order) where T : IEntity
     27         {
     28             if (order == null)
     29             {
     30                 if (where == null)
     31                 {
     32                     return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll();
     33                 }
     34                 else
     35                 {
     36                     return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(IWhere2ICriterion(where));
     37                 }
     38             }
     39             else if (where == null)
     40             {
     41                 return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(order as NHibernate.Expression.Order[]);
     42             }
     43 
     44             return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(order as NHibernate.Expression.Order[], IWhere2ICriterion(where));
     45         }
     46 
     47         public IEnumerable<T> FindAll<T>(int pageIndex, int pageSize, IWhere[] where, IOrder[] order, out int count) where T : IEntity
     48         {
     49             if (where == null)
     50             {
     51                 count = Castle.ActiveRecord.ActiveRecordMediator.Count(typeof(T));
     52                 if (order == null) {
     53                     return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize);
     54 
     55                 }else{
     56                     return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize, order as NHibernate.Expression.Order[]);
     57                 }
     58             }
     59             else
     60             {
     61                 count = Castle.ActiveRecord.ActiveRecordMediator.Count(typeof(T), IWhere2ICriterion(where));
     62                 if (order == null) {
     63                     return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize, IWhere2ICriterion(where));
     64                 }
     65             }
     66             return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize, order as NHibernate.Expression.Order[], IWhere2ICriterion(where));
     67         }
     68 
     69         public void Add<T>(T entity) where T : IEntity
     70         {
     71             using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
     72             {
     73                 (entity as Castle.ActiveRecord.ActiveRecordBase).CreateAndFlush();
     74                 tran.VoteCommit();
     75             }
     76         }
     77 
     78         public void Delete<T>(T entity) where T : IEntity
     79         {
     80             using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
     81             {
     82                 (entity as Castle.ActiveRecord.ActiveRecordBase).DeleteAndFlush();
     83                 tran.VoteCommit();
     84             }
     85         }
     86 
     87         public void DeleteAll<T>() where T : IEntity
     88         {
     89             using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
     90             {
     91                 Castle.ActiveRecord.ActiveRecordBase<T>.DeleteAll();
     92                 tran.VoteCommit();
     93             }
     94         }
     95 
     96         public void DeleteAll<T>(IWhere[] where) where T : IEntity
     97         {
     98             IEnumerable<T> entities;
     99             if (where == null)
    100             {
    101                 entities = this.FindAll<T>();
    102             }
    103             else
    104             {
    105                 entities = this.FindAll<T>(where);
    106             }
    107             if (entities != null)
    108             {
    109                 using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
    110                 {
    111                     foreach (T entity in entities) {
    112                         this.Delete<T>(entity);
    113                     }
    114                     tran.VoteCommit();
    115                 }
    116             }
    117         }
    118         public void DeleteAll<T>(string where) where T : IEntity
    119         {
    120 
    121             using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
    122             {
    123                 Castle.ActiveRecord.ActiveRecordBase<T>.DeleteAll(where);
    124                 tran.VoteCommit();
    125             }
    126 
    127         }
    128         public void DeleteAll<T>(IEnumerable<string> pkValues) where T : IEntity
    129         {
    130             using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
    131             {
    132                 Castle.ActiveRecord.ActiveRecordBase<T>.DeleteAll(pkValues);
    133                 tran.VoteCommit();
    134             }
    135         }
    136 
    137         public void Update<T>(T entity) where T : IEntity
    138         {
    139             using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
    140             {
    141                 (entity as Castle.ActiveRecord.ActiveRecordBase).UpdateAndFlush();
    142                 tran.VoteCommit();
    143             }
    144         }
    145 
    146         public bool Exists<T>(string primaryKey) where T : IEntity
    147         {
    148             return Castle.ActiveRecord.ActiveRecordBase<T>.Exists<string>(primaryKey);
    149         }
    150         #endregion
    151         #region ado执行sql
    152         public int ExecuteSql(string sql, params System.Data.IDataParameter[] ps)
    153         {
    154             using (System.Data.IDbCommand cmd = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(CastleSinglePrimaryKeyRepository)).Connection.CreateCommand())
    155             {
    156                 cmd.CommandText = sql;
    157                 if (ps != null && ps.Length > 0)
    158                 {
    159                     foreach (System.Data.IDataParameter p in ps)
    160                     {
    161                         cmd.Parameters.Add(p);
    162                     }
    163                 }
    164                 return cmd.ExecuteNonQuery();
    165             }
    166         }
    167 
    168         public object ExecuteScalar(string sql, params System.Data.IDataParameter[] ps)
    169         {
    170             using (System.Data.IDbCommand cmd = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(CastleSinglePrimaryKeyRepository)).Connection.CreateCommand())
    171             {
    172                 cmd.CommandText = sql;
    173                 if (ps != null && ps.Length > 0)
    174                 {
    175                     foreach (System.Data.IDataParameter p in ps)
    176                     {
    177                         cmd.Parameters.Add(p);
    178                     }
    179                 }
    180                 return cmd.ExecuteScalar();
    181             }
    182         }
    183 
    184         public System.Data.DataTable ExecuteDataTable(string sql, params System.Data.IDataParameter[] ps)
    185         {
    186             using (System.Data.IDbCommand cmd = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(CastleSinglePrimaryKeyRepository)).Connection.CreateCommand())
    187             {
    188                 cmd.CommandText = sql;
    189                 if (ps != null && ps.Length > 0)
    190                 {
    191                     foreach (System.Data.IDataParameter p in ps)
    192                     {
    193                         cmd.Parameters.Add(p);
    194                     }
    195                 }
    196                 System.Data.DataTable result = new System.Data.DataTable();
    197                 result.Load(cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection));
    198                 return result;
    199             }
    200         }
    201         #endregion
    202         #endregion
    203         #region 其他方法
    204         NHibernate.Expression.ICriterion[] IWhere2ICriterion(IWhere[] where)
    205         {
    206             if (where == null) {
    207                 return null;
    208             }
    209             NHibernate.Expression.ICriterion[] wheres = new NHibernate.Expression.ICriterion[where.Length];
    210             for (var i = 0; i < where.Length; i++)
    211             {
    212                 wheres[i] = (where[i] as WhereBase).Instance;
    213             }
    214             return wheres;
    215         }
    216         #endregion
    217     }
    218 }
    复制代码

    Castle实现IReposoitory

    五、项目开发的层次结构                                                                                              

     
     
  • 相关阅读:
    ios状态栏
    RGBA设置颜色
    应用程序的生命周期(转)
    UIViewController的生命周期
    UIViewController的创建
    UIButton
    NSUserDefaults
    打印结构体
    iOS 界面间的传值 属性传值 代理传值
    如何安装Homebrew
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3298103.html
Copyright © 2011-2022 走看看