我的ORM發展史


    之所以叫這個名字是因為我也在重復造輪子寫了個ORM框架,從08年到現在,隨着技術的累計對這其中的一些東西也有些領悟,恰巧今天的推薦頭條也是關於ORM的,恰巧本人今天出差比較閑散,於是就忍不住要來獻一下丑了.

    起初,也就是08年,那會本人才剛從學校畢業,那會只知道PetShop比較出名,業界聲譽較好,據說性能可以完勝Java,於是便學習了起來,從此以后在做所有項目必然出現DAL,BLL,Model這3層,由於大多項目根本沒有跨數據庫的需求,於是里面神馬工廠模式,MySqlHelper,OracleHelper就全部丟掉了,唯一留下來的只有光榮的SqlHelper,那時SqlHelper的ExecuteDataReader,ExecuteNonequery,ExecuteDataset是屢試不爽啊.不過人總是懶惰和不安於現狀的,后來還是覺得麻煩便萌生了寫個工具去生成那些機械的DAL,BLL,Model,說干就干,便有了以下代碼

 

public classs User
{
    public  string Id { get; set;}
     public  string Name{ get; set;}
     public  string Password{ get; set;}
     public  string Sex{ get; set;}
     public DateTime Birthday{ get; set;}
}

 

public  class UserDAL
{
   pbblic  void Insert(User user)
   {
       SqlParameter[] para = user.ToParameters();
       SqlHelper.ExecNonequery(CommandType.StoreProcdure,  " InsertUser ",para);
   }
   
    public  void Delete( int id)
   {
       SqlParameter[] para = id.ToParameters();
       SqlHelper.ExecNonequery(CommandType.StoreProcdure,  " DeleteUserById ",para);
   }

    public  void Update(User user)
   {
       SqlParameter[] para = user.ToParameters();
       SqlHelper.ExecNonequery(CommandType.StoreProcdure,  " UpdateUserById ",para);
   }

    public List<User>  GetUserList()
   {
       List<User>  userList =  new List<User>();
       DataReader dr = SqlHelper.ExecDatareaderr(CommandType.StoreProcdure,  " GetUserList ", null);
        return dr.ToList<User>();
   }
}

 

 

public  class UserBLL
{
    private  readonly UserDAL _userDAL =  new UserDAL();
   pbblic  void Insert(User user)
   {
       _userDAL.Insert(user);       
   }
   
    public  void Delete( string id)
   {
        _userDAL.Delete(id);      
   }

    public  void Update(User user)
   {
        _userDAL.Update(user);       
   }

    public List<User>  GetUserList()
   {
         return  _userDAL.GetUserList();   
   }
}

 

       怎么樣,很熟悉吧,不過以上代碼都是臨時敲的,是偽代碼,實際提供的方法可能更多,不過結構跟這個大同小異.工具的原理便是從數據庫讀出表的信息來,生成存儲過程和這3層代碼,使用的時候只需要把生成的sql執行一遍,再拷貝代碼文件到項目里就行了,如果剛建項目的話,甚至可以連項目文件一起生成,剛寫好這個工具的時候的確感覺小有所成啦.

 

      又過了一段時間,突然覺得好像還是很繁瑣,比如數據庫如果改了一個字段,我就要從新生成,從新執行sql,從新覆蓋Model,DAL,BLL,更加致命的是,我沒有辦法去寫一些更上層通用的方法,比如,我寫一個表數據查看功能,我就需要在這個頁面寫很多case

      假設這個頁面接受參數tablename,我便需要這樣寫:

 

switch(tablename)
{
    case  " User ":
      UserBLL bll =  new UserBLL();
      dataGrid.DataSource = bll.GetList();
    break;
    case  " Product ":
      ProductBLL bll =  new ProductBLL();
      dataGrid.DataSource = bll.GetList();
    break;
    case  " Log ":
      LogBLL bll =  new LogBLL();
      dataGrid.DataSource = bll.GetList();
    break;

}

 

      很明顯同樣的代碼我需要寫很多遍,先不說優不優雅,起碼比較麻煩,沒達到我們前面說的"人都是懶的"這一目的.我們要怎么改進呢,可能有人會說給BLL加上IBLL,那樣可以把case里的dataGrid.DataSource = bll.GetList();這一句話給放到switch塊外面.也就是這樣

 

switch(tablename)
{
   IBLL bll;
    case  " User ":
      bll =  new UserBLL();
    break;
    case  " Product ":
      bll =  new ProductBLL();
    break;
    case  " Log ":
      bll =  new LogBLL();
    break;
}
dataGrid.DataSource = bll.GetList();

 

    還有人可能會說用反射,可是這里我們先不說這點,當然這樣可以解決問題,我們說上面一種方式,我們需要引入接口,定義IBLL,如下

 

public  interface IBLL<T>  where T: class
{
     void Insert(T model);
     void Delete( string id);
     void Update(T model);
    List<T>  GetList();
}

 

   然后將BLL層這樣改

 

public  class UserBLL:IBLL<User>
{
    // 跟上面的UserBLL一樣,此處略
}

 

   好,收工.可是做好了這步,第一還是沒解決,一改數據庫就要去執行sql,覆蓋DAL,BLL,Model,為了解決這些問題,我決定

        1.將存儲過程方式改為生成sql方式(要實現這一點我們就的定義很多特性(Attrbute))

        2.將BLL層拿掉,因為在這里,沒有意義,也就是大家都在說的未了分層而分層,層次顯得太過僵硬做作.

        3.只生成Model層,DAL定義泛型接口,所有實現走框架(現在才能算框架,以上其實就是代碼生成器)

 

   經過改進便有了如下代碼:   

 

Model
// ------------------------------------------------------------------------------
//  <auto-generated>
//      This code generated by the tool, do not propose to amend
//        Generation time:2012/7/16 18:01:46
//  </auto-generated>
// ------------------------------------------------------------------------------
using System;
using System.Data;
using System.Runtime.Serialization;
using XDbFramework;
using System.Xml.Serialization;
using System.Diagnostics;
using System.CodeDom.Compiler;

namespace Model
{
    [Serializable]
    [Table(TableName =  " Admin " ,Descripton =  " 管理員 ")]
    [GeneratedCodeAttribute( " System.Xml "" 2.0.50727.4927 ")]
    [DebuggerStepThroughAttribute()]
    [XmlRootAttribute(Namespace =  " http://www.scexin.com/ ", IsNullable =  true)]
    [DataContract(Namespace =  " http://www.scexin.com/ ")]
     public  partial  class Model_Admin
    {
        
        [Column(KeyType = KeyTypeEnum.PrimaryKey,ColumnName= " AdminID ",DbType=SqlDbType.Int, Index= 0,Description= " 管理員編號 ")]
        [DataMember(Order =  0)]
         public   int? AdminID{ get; set;}
    
        
        [Column(ColumnName= " Passport ",DbType=SqlDbType.VarChar, Index= 1,Description= " 帳號 ")]
        [DataMember(Order =  1)]
         public   string Passport{ get; set;}
    
        
        [Column(ColumnName= " Password ",DbType=SqlDbType.VarChar, Index= 2,Description= " 密碼 ")]
        [DataMember(Order =  2)]
         public   string Password{ get; set;}
    
        
        [Column(ColumnName= " AddTime ",DbType=SqlDbType.DateTime, Index= 3,Description= " 操作時間 ")]
        [DataMember(Order =  3)]
         public  DateTime? AddTime{ get; set;}
    
    }    
}

  

SqlAccessor
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Text;
using XDbFramework.Linq;
using System.Linq;

namespace XDbFramework
{
     public  class SqlAccessor<T> : IDbExceuteAble, IDAL<T>  where T :  class, new()
    {
         #region private fileds
         private  const  string InsertSqlFormat =  " INSERT INTO [{0}] ({1}) VALUES({2}) ";
         private  const  string UpdateSqlFormat =  " UPDATE [{0}] SET {1} WHERE {2} ";
         private  const  string DeleteSqlFormat =  " DELETE [{0}] WHERE {1} ";
         private  const  string SelectFormat =  " SELECT {0} FROM {1} ";
         private  const  string SelectByWhereFormat =  " SELECT {0} FROM {1} WHERE {2} ";
         private  const  string SelectByWherePaginationFormat =  @" WITH ORDEREDRESULTS AS 
(
    SELECT {0}, ROW_NUMBER() 
        OVER 
        (
            ORDER BY {1}
        ) 
    AS ROWNUMBER 
    FROM [{2}]  WHERE {3}
)  SELECT {4} FROM ORDEREDRESULTS WHERE ROWNUMBER BETWEEN {5} AND {6}
SELECT COUNT(*) AS [COUNT] FROM [{7}] WHERE {8}
";
         private  static  readonly TableAttribute TableInfo = DalHelper<T>.GetTableInfo();
         private ExecNonQuery _execNonQuery = (a, b, c) => SqlHelper.ExecuteNonQuery(a, b, (SqlParameter[])c);
         private ExecDataReader _execDataReader = (a, b, c) => SqlHelper.ExecuteReader(a, b, (SqlParameter[])c);
         private  readonly LinqQueryProvider<T> _linqQueryProvider;
         #endregion

         #region private methods
         private DbExecuteState UpdateWithPredicate(T t, Predicate<ColumnAttribute> predicate =  null)
        {
             var sb =  new StringBuilder();
             var pk = DalHelper<T>.GetPrimaryKeyInfo(t);
             var columList = DalHelper.GetTypeColumns(t);
             var uColumns =  new UpdateColumns();
             foreach (ColumnAttribute col  in columList)
            {
                 if (col.ColumnName != pk.ColumnName && (predicate ==  null || predicate(col)))
                {
                    uColumns.Add(col.ColumnName, col.Value, col.ParameterType);
                }
            }
             var condition =  new Query(pk.ColumnName, CompareOperators.Equal, pk.Value, pk.OperatorType);
            sb.AppendFormat(UpdateSqlFormat, TableInfo.TableName, uColumns.SqlString, condition.SqlString);
            ExecNonQuery(CommandType.Text, sb.ToString(),  null);
             return DbExecuteState.Succeed;
        }


         #endregion

         #region constructor
         public SqlAccessor()
        {
            _linqQueryProvider =  new LinqQueryProvider<T>( this);
        }
         #endregion

         #region public method
         public  void Insert(T t)
        {
             var sb =  new StringBuilder();
             var columns =  new StringBuilder();
             var columnsParameter =  new StringBuilder();
             var pk =DalHelper<T>.GetPrimaryKeyInfo();
             var columList = DalHelper.GetTypeColumns(t);
             var index =  0;
             if (!TableInfo.GenreratePK)
            {
                columList.RemoveAll(c => c.ColumnName ==pk.ColumnName);
            }
             var paras =  new SqlParameter[columList.Count];
             foreach (ColumnAttribute col  in columList)
            {
                columns.AppendFormat( " [{0}] ", col.ColumnName);
                columnsParameter.AppendFormat( " @p_{0} ", col.ColumnName);
                 if (index != columList.Count -  1)
                {
                    columns.Append( " , ");
                    columnsParameter.Append( " , ");
                }
                paras[index] =  new SqlParameter( string.Format( " @p_{0} ", col.ColumnName), (SqlDbType)col.DbType, col.FiledLength) { Value = col.Value.GetDbValue() };
                index++;
            }
            sb.Append( string.Format(InsertSqlFormat, TableInfo.TableName, columns.ToString(), columnsParameter.ToString()));
            ExecNonQuery(CommandType.Text, sb.ToString(), paras);
             var dr = ExecDataReader(CommandType.Text,  string.Format( " Select * from [{0}] where [{1}] = IDENT_CURRENT('{2}') ", TableInfo.TableName, pk.ColumnName, TableInfo.TableName),  null);
             var insertT = DalHelper<T>.ToEntity(dr,  true);
            DalHelper<T>.SetPrimaryKeyValue(t, DalHelper<T>.GetPrimaryKeyValue(insertT));
        }

         public DbExecuteState Delete( object id)
        {
            T t =  new T();
            DalHelper<T>.SetPrimaryKeyValue(t, id);
             return Delete(t);

        }

         public DbExecuteState Delete(T t)
        {
             var sb =  new StringBuilder();
             var pk = DalHelper<T>.GetPrimaryKeyInfo(t);
            sb.AppendFormat(DeleteSqlFormat, TableInfo.TableName,  string.Format( " {0}=@p_{1} ", pk.ColumnName, pk.ColumnName));
             var para =  new SqlParameter() { ParameterName =  " @p_ " + pk.ColumnName, Value = pk.Value, SqlDbType = (SqlDbType)pk.DbType };
            ExecNonQuery(CommandType.Text, sb.ToString(),  new SqlParameter[] { para });
             return DbExecuteState.Succeed;
        }




         public DbExecuteState Update(T t)
        {
             return UpdateWithPredicate(t);
        }

         public DbExecuteState UpdateIgnoreNull(T t)
        {
             return UpdateWithPredicate(t, col => !col.Value.IsDBNull());
        }

         public DbExecuteState UpdateSingleColumn(T t,  string columName,  object columValue)
        {
            DalHelper.SetModelValue(t, columName, columValue);
             return UpdateWithPredicate(t, col => col.ColumnName == columName);
        }

         public DbExecuteState UpdateSingleColumn( object id,  string columName,  object columValue)
        {
            T t =  new T();
            DalHelper<T>.SetPrimaryKeyValue(t, id);
            DalHelper.SetModelValue(t, columName, columValue);
             return UpdateWithPredicate(t, col => col.ColumnName == columName);
        }

         public  bool Exists(T t)
        {
             var lst = GetList(t);
             return lst !=  null && lst.Count >  0;
        }

         public  long GetCount()
        {
             var sb =  new StringBuilder();
            sb.AppendFormat(SelectFormat,  " count(*) ", TableInfo.TableName);
             var dr = ExecDataReader(CommandType.Text, sb.ToString(),  null);
             try
            {
                dr.Read();
                 return dr[ 0].ToString().AsInt();
            }
             finally
            {
                dr.Close();
                dr.Dispose();
            }

        }

         public  decimal Sum(Selector<T> selector,  string column)
        {
             return Cacl(selector,  string.Format( " SUM({0}) ", column));
        }

         public  decimal Avg(Selector<T> selector,  string column)
        {
             return Cacl(selector,  string.Format( " AVG({0}) ", column));
        }

         private  long Cacl(Selector<T> selector,  string express)
        {
             var sb =  new StringBuilder();
             var condition = selector.Condition;
            sb.AppendFormat(SelectByWhereFormat, express, TableInfo.TableName, condition.SqlString);
             var dr = ExecDataReader(CommandType.Text, sb.ToString(),  null);
             try
            {
                dr.Read();
                 return dr[ 0].ToString().AsInt();
            }
             finally
            {
                dr.Close();
                dr.Dispose();
            }
        }

         public  long GetCount(Selector<T> selector)
        {
             if (selector ==  null)
                 return GetCount();
             return Cacl(selector,  " count(*) ");
        }

         public  object GetResult(Selector<T> selector)
        {
             return GetResult< object>(selector);
        }


         public TResult GetResult<TResult>(Selector<T> selector)
        {
             var sb =  new StringBuilder();
             var condition = selector.Condition;
            sb.AppendFormat(SelectByWhereFormat, selector.Colums, TableInfo.TableName, condition.SqlString);
             var dr = ExecDataReader(CommandType.Text, sb.ToString(),  null);
             try
            {
                dr.Read();
                 return (TResult)dr[ 0];
            }
             finally
            {
                dr.Close();
                dr.Dispose();
            }
        }

         public T GetSingle(T t)
        {
             var list = GetList(t);
             if (list !=  null && list.Count >  0)
                 return list[ 0];
             return  null;
        }

         public T GetSingle( object id)
        {
             var t =  new T();
            DalHelper<T>.SetPrimaryKeyValue(t, id);
             return GetSingle(t);
        }

         public T GetSingle(Selector<T> selector)
        {
             var list = GetList(selector);
             if (list ==  null || list.Count <=  0)
                 return  null;
             return list[ 0];
        }

         public List<T> GetList()
        {
             var sb =  new StringBuilder();
            sb.AppendFormat(SelectFormat,  " * ", TableInfo.TableName);

             var dr = ExecDataReader(CommandType.Text, sb.ToString(),  null);
             var lst = DalHelper<T>.ToList(dr, closeDataReader:  true);
             return lst;
        }

         public List<T> GetList(Pagination pagination)
        {
             return GetList( new Selector<T>() { Pagination = pagination });
        }



         public List<T> GetList(Selector<T> selector)
        {
             var pk = DalHelper<T>.GetPrimaryKeyInfo();
             var columns = DalHelper.GetTypeColumns<T>();
             var sb =  new StringBuilder();
             var condition = selector.Condition;
             string  where = condition ==  null ?  string.Empty : condition.SqlString;
             where =  string.IsNullOrEmpty( where) ?  " 1=1 " :  where;
             var orderBy = selector.Order ==  null 
                ? (pk ==  null ? columns[ 0].ColumnName : pk.ColumnName) 
                : selector.Order.ToSqlString(needPredicate:  true);
            sb.AppendFormat(SelectByWherePaginationFormat,
                selector.Colums,
                orderBy,
                TableInfo.TableName,
                 where,
                selector.Colums,
                selector.Pagination.Offset,
                selector.Pagination.Offset + selector.Pagination.PageSize,
                TableInfo.TableName,
                 where);
             var dr = ExecDataReader(CommandType.Text, sb.ToString(),  null);
             try
            {
                 var lst = DalHelper<T>.ToList(dr);
                 if (dr.NextResult())
                {
                    dr.Read();
                    selector.Pagination.RecordCount = dr[ 0].ToString().AsInt();
                }
                 return lst;
            }
             finally
            {
                dr.Close();
                dr.Dispose();
            }
        }

         public List<T> GetList(T t)
        {
             var sb =  new StringBuilder();
             var condition =  new Selector<T>(t,  nullnull).Condition;
            sb.AppendFormat(SelectByWhereFormat,  " * ", TableInfo.TableName, condition.SqlString);
             var dr = ExecDataReader(CommandType.Text, sb.ToString(),  null);
             return DalHelper<T>.ToList(dr, closeDataReader:  true);
        }

         public List<T> Where(System.Linq.Expressions.Expression<Func<T,  bool>> predicate)
        {
            IQueryable<T> tList = _linqQueryProvider.Where(predicate);
             return tList.ToList();
        }

         public T Single(System.Linq.Expressions.Expression<Func<T,  bool>> predicate)
        {
            List<T> list = Where(predicate);
             if (list !=  null && list.Count >  0)
                 return list[ 0];
             throw  new XDbException( " 未找到滿足條件的項 ");
        }

         public T SingleOrDefault(System.Linq.Expressions.Expression<Func<T,  bool>> predicate)
        {
            List<T> list = Where(predicate);
             if (list !=  null && list.Count >  0)
                 return list[ 0];
             return  default(T);
        }

         public  int Count(System.Linq.Expressions.Expression<Func<T,  bool>> predicate)
        {
             return _linqQueryProvider.Count(predicate);
        }

         public ExecNonQuery ExecNonQuery
        {
             get
            {
                 return _execNonQuery;
            }
             set
            {
                 if (value !=  null)
                    _execNonQuery = value;
            }
        }
         public ExecDataReader ExecDataReader
        {
             get
            {
                 return _execDataReader;
            }
             set
            {
                 if (value !=  null)
                    _execDataReader = value;
            }
        }
         #endregion

         public IEnumerator<T> GetEnumerator()
        {
             return _linqQueryProvider.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
             return _linqQueryProvider.GetEnumerator();
        }

         public Type ElementType
        {
             get {  return  typeof(T); }
        }

         public System.Linq.Expressions.Expression Expression
        {
             get {  return _linqQueryProvider.Expression; }
        }

         public IQueryProvider Provider
        {
             get {  return _linqQueryProvider.Provider; }
        }

    }
}

   

DataContext
// ------------------------------------------------------------------------------
//  <auto-generated>
//      This code generated by the tool, do not propose to amend. 
//        Generation time:2012/4/27 9:32:20
//  </auto-generated>
// ------------------------------------------------------------------------------

using System;
using ExinSoft.Host.Model;
using XDbFramework;

namespace DALFactory
{
     public  partial  class DataContext : IDisposable
    {
       
         public IDAL<Model_Account> Account
        {
             get
            {
                 return _da.CreateDAL<Model_Account>();
            }
        }
         public IDAL<Model_AccountOfReceiptsAndPayments> AccountOfReceiptsAndPayments
        {
             get
            {
                 return _da.CreateDAL<Model_AccountOfReceiptsAndPayments>();
            }
        }
         public IDAL<Model_AccountSnapshotRepository> AccountSnapshotRepository
        {
             get
            {
                 return _da.CreateDAL<Model_AccountSnapshotRepository>();
            }
        }
         public IDAL<Model_Admin> Admin
        {
             get
            {
                 return _da.CreateDAL<Model_Admin>();
            }
        }
       
     
    }
}

 

以上提供了核心類的實現方式,下面我們來看看調用方式,看是否優雅,框架實現的功能有,普通CRUD,存儲過程執行,查詢提供兩種方式,即普通方式和Linq方式,如:

普通方式:

DataContext.Invoke(context =>
            {
                 var selector = Selector<Model_Admin>
                    .NewQuery(m => m.AdminID >=  1) //開始一個查詢
                    .Or(m => m.AdminID <  5)   //Or連接
                    .And(m => m.AddTime >  new DateTime( 201011))  //And連接
                    .And(m => m.AddTime <  new DateTime( 201211))
                    .Page( 110//分頁,此處為第一頁,每頁10條
                    .Ascending(m => m.AdminID); //按AdminID升序排列
                 var list = context.Admin.GetList(selector);
            });

Linq方式: 

DataContext.Invoke(context =>
            {
                 var r =  from a  in context.Admin  where a.AdminID ==  1  select a;
                 var c = r.Count();
            });

 

存儲過程支持:  

代碼
  public  class GetServiceReceiptsAndPaymentsResult
    {
         public  int ServiceID {  getset; }
         public  decimal? sumMoney {  getset; }
    }

    [DbCommand( " GetServiceReceiptsAndPayments ")]
     public  class GetServiceReceiptsAndPayments
    {
        [DbParameter( " AccountID ")]
         public  int? AccountID {  getset; }

        [DbParameter( " StartTime ")]
         public DateTime? StartTime {  getset; }
        [DbParameter( " EndTime ")]
         public DateTime? EndTime {  getset; }

    }

using ( var context =  new DataContext())
            {
                 var result = context.SearchResultFromProcedure<GetServiceReceiptsAndPaymentsResult, GetServiceReceiptsAndPayments>( new GetServiceReceiptsAndPayments
                {
                    AccountID =  1,
                    StartTime =  new DateTime( 201011),
                    EndTime =  new DateTime( 201211)
                }); // 傳遞參數並獲取列表
                Assert.AreNotEqual(result,  null);
            }

       

 

  
   using (DataContext context =  new DataContext())
  {
      long  customCode = context.GetSingleValueFormProcedure< long>( " CreateMaxOrderWithArea "new { @AreaId = areaid}); // 參數使用匿名類方式傳入,此處表示調用存儲過程 CreateMaxOrderWithArea 並返回一個64位整型的客戶編號

  } 

      

更多方式:

調用方式
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using ExinSoft.Host.DALFactory;
using ExinSoft.Host.Model;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using XDbFramework;

namespace XDBFrameworkText
{
    [TestClass]
     public  class UnitTest1
    {
        [TestMethod]
         public  void InsertTest()
        {
             string passport =  " x " + DateTime.Now.Ticks;
             var admin =  new Model_Admin { AddTime = DateTime.Now, Passport = passport, Password =  " 123456 " };
             using ( var context =  new DataContext())
            {
                context.Admin.Insert(admin);
                Model_Admin insertedAdmin = context.Admin.GetSingle( new Model_Admin { Passport = passport });
                Assert.AreEqual(admin.Passport, insertedAdmin.Passport);
            }
        }

        [TestMethod]
         public  void UpdateTest()
        {
             using ( var context =  new DataContext())
            {
                Model_Admin admin = context.Admin.GetSingle( new Model_Admin { AdminID =  11 });
                admin.Password =  "" + DateTime.Now.Ticks;
                context.Admin.UpdateSingleColumn(admin,  " Password ", admin.Password);

                Model_Admin admin1 = context.Admin.GetSingle( new Model_Admin { AdminID =  11 });
                Assert.AreEqual(admin.Password, admin1.Password);
            }
        }

        [TestMethod]
         public  void DeleteTest()
        {
             using ( var context =  new DataContext())
            {
                 var admin =  new Model_Admin { AdminID =  17 };

                context.Admin.Delete(admin);

                Model_Admin admin1 = context.Admin.GetSingle( new Model_Admin { AdminID =  17 });

                Assert.AreEqual(admin1,  null);
            }
        }

        [TestMethod]
         public  void GetSingleTest()
        {
             using ( var context =  new DataContext())
            {
                Model_Admin admin = context.Admin.GetSingle( new Model_Admin { AdminID =  11 });

                Assert.AreEqual(admin.AdminID,  11);
            }
        }

        [TestMethod]
         public  void GetListTest()
        {
             using ( var context =  new DataContext())
            {
                List<Model_Admin> adminList = context.Admin.GetList();
                Assert.AreNotEqual(adminList.Count,  0);
            }
        }


        [TestMethod]
         public  void WhereTest()
        {
             using ( var context =  new DataContext())
            {
                 var adminList = context.Admin.Where(m => m.AdminID ==  11).ToList();
                Assert.AreEqual(adminList[ 0].AdminID,  11);
            }
        }

        [TestMethod]
         public  void SingleTest()
        {
             using ( var context =  new DataContext())
            {
                Model_Admin admin = context.Admin.Single(m => m.AdminID ==  11);
                Assert.AreEqual(admin.AdminID,  11);
            }
        }


         public  static  readonly  string BuyProduct_Code =  " 1105 ";
        [TestMethod]
         public  void SingleTest2()
        {
             using ( var context =  new DataContext())
            {
                 var server = context.Services.Single(m => m.ServiceCode == BuyProduct_Code);
                Assert.AreEqual(server.ServiceID,  10);
            }
        }

        [TestMethod]
         public  void SingleOrDefaultTest()
        {
             using ( var context =  new DataContext())
            {
                 var aid =  11;
                Model_Admin admin = context.Admin.SingleOrDefault(m => m.AdminID == aid);
                Assert.AreEqual(admin.AdminID,  11);
            }
        }

        [TestMethod]
         public  void PageTest()
        {
             using ( var context =  new DataContext())
            {
                List<Model_Admin> adminList = context.Admin.GetList( new Selector<Model_Admin>
                                                                        {
                                                                            Pagination =  new Pagination
                                                                                             {
                                                                                                 PageIndex =  1,
                                                                                                 PageSize =  2
                                                                                             }
                                                                        });
                Assert.AreEqual(adminList.Count,  2);
            }
        }

        [TestMethod]
         public  void SelectorTest()
        {
             using ( var context =  new DataContext())
            {
                 var selector =  new Selector<Model_Admin>
                                   {
                                       MinObj =  new Model_Admin
                                                    {
                                                        AdminID =  1
                                                    },
                                       MaxObj =  new Model_Admin
                                                    {
                                                        AdminID =  11
                                                    },
                                       Pagination =  new Pagination
                                                    {
                                                        PageIndex =  1,
                                                        PageSize =  2
                                                    }
                                   };
                List<Model_Admin> adminList = context.Admin.GetList(selector);
                Assert.AreEqual(selector.Pagination.RecordCount,  9);
            }
        }

        [TestMethod]
         public  void QueryTest()
        {
            DataContext.Invoke(context =>
            {
                 var selector = Selector<Model_Admin>
                    .NewQuery(m => m.AdminID >=  1)
                    .And(m => m.AdminID <  5)
                    .And(m => m.AddTime >  new DateTime( 201011))
                    .And(m => m.AddTime <  new DateTime( 201211))
                    .Page( 110)
                    .Ascending(m => m.AdminID);
                 var list = context.Admin.GetList(selector);
                Assert.AreNotEqual(list,  null);
            });
        }

        [TestMethod]
         public  void LinqTest1()
        {
            DataContext.Invoke(context =>
            {
                 var r =  from a  in context.Admin  where a.AdminID ==  1  select a;
                 var c = r.Count();

                Assert.AreEqual(c,  1);
            });
        }

        [TestMethod]
         public  void LinqTest2()
        {
            DataContext.Invoke(context =>
            {
                 var r =  from a  in context.Admin  where a.AdminID ==  1  select a;
                 var list = r.ToList();
                Assert.AreNotEqual(list,  null);
            });
        }

        [TestMethod]
         public  void LinqTest3()
        {
            DataContext.Invoke(context =>
            {
                 var r =  from a  in context.Admin  where a.AdminID ==  1 && a.Passport ==  " admin "  select a;
                 var list = r.ToList();
                Assert.AreNotEqual(list,  null);
            });
        }

        [TestMethod]
         public  void LinqTest4()
        {
            DataContext.Invoke(context =>
            {
                 var r =  from a  in context.Admin  where a.AdminID ==  1 || a.Passport.Contains( " admin ") || a.Password.StartsWith( " 123 ") || a.Password.EndsWith( " 456 "select a;
                 var list = r.ToList();
                Assert.AreNotEqual(list,  null);
            });
        }

        [TestMethod]
         public  void LinqTest5()
        {
            DataContext.Invoke(context =>
                                   {
                                        var r =  from a  in context.AdminHasRight
                                                where a.AdminID ==  1
                                                select a;
                                        var list = r.ToList();
                                       Assert.AreNotEqual(list,  null);
                                   });
        }


        [TestMethod]
         public  void TransactionTest()
        {
             using ( var context =  new DataContext())
            {
                 long count = context.Admin.Count();
                 var a = DataContextStatic.Recharge.Count(s => s.State == Convert.ToInt32( 1));
                 string passport =  " x " + DateTime.Now.Ticks;
                context.BeginTransaction();
                 try
                {
                    context.Admin.Insert( new Model_Admin
                                             {
                                                 Passport = passport,
                                                 Password =  " 123456 ",
                                                 AddTime = DateTime.Now
                                             });
                    context.Admin.Insert( new Model_Admin
                                             {
                                                 Passport = passport +  " _2 ",
                                                 Password =  " 123456 ",
                                                 AddTime = DateTime.Now
                                             });
                    context.CommitTransaction();
                }
                 catch
                {
                    context.RollbackTransaction();
                }

                Assert.AreEqual(count, context.Admin.GetCount() -  2);
            }
        }


        [TestMethod]
         public  void ProcTest1()
        {
             using ( var context =  new DataContext())
            {
                context.ExecuteProcedure( " ClearingAccount ");
            }
        }

        [TestMethod]
         public  void ProcTest2()
        {
             using ( var context =  new DataContext())
            {
                 var result = context.SearchResultFromProcedure<GetServiceReceiptsAndPaymentsResult, GetServiceReceiptsAndPayments>( new GetServiceReceiptsAndPayments
                {
                    AccountID =  1,
                    StartTime =  new DateTime( 201011),
                    EndTime =  new DateTime( 201211)
                });
                Assert.AreNotEqual(result,  null);
            }
        }

         public  void TestTmp()
        {
             var selector = Selector<Model_AirTicket>
                .NewQuery(m => m.OrderID ==  " 123 ")
                .Or(m => m.UIdCard ==  " 123 ");
             var query = Query<Model_AirTicket>
                .Where(air => air.AddTime >=  new DateTime( 201211))
                .And(air => air.AddTime <  new DateTime( 20121231));
            selector.Condition.Connect(query, LogicOperators.Or);

        }



        [TestMethod]
         public  void TestTmp1()
        {



             var airticket =  new
                                {
                                    ShopID =  1,
                                    IdCard =  " 456 ",
                                    OrderId =  "",
                                    StartTime =  new DateTime( 201211),
                                    EndTime =  new DateTime( 2012121)
                                };
             var t =  new Model_AirTicket() { ShopID =  123 };
             var selector = Selector<Model_AirTicket>
                .NewQuery(air => air.ShopID == t.ShopID)
                .Or(air => air.UIdCard == airticket.IdCard)
                .Or(air => air.OrderID ==  " 789 ")
                .Or(air => air.AddTime >= airticket.StartTime)
                .Or(air => air.AddTime < airticket.EndTime);
             using (DataContext context =  new DataContext())
            {
                 var list = context.AirTicket.GetList(selector);
            }

        }


        [TestMethod]
         public  void TestTmp2()
        {
             var airticket =  new
                               {
                                   ShopID =  1,
                                   IdCard =  "",
                                   OrderId =  "",
                                   StartTime =  new DateTime( 201211),
                                   EndTime =  new DateTime( 2012121)
                               };

             using (DataContext context =  new DataContext())
            {
                 var list =  from a  in context.AirTicket  where a.ShopID == airticket.ShopID  select a;
                 var t = list.ToList();
            }
        }

        [TestMethod]
         public  void TestCount()
        {
             var aa =  1;
             var a = DataContextStatic.Recharge.Count(s => s.State == Convert.ToInt32(aa));
        }
    }

     public  class GetServiceReceiptsAndPaymentsResult
    {
         public  int ServiceID {  getset; }
         public  decimal? sumMoney {  getset; }
    }

    [DbCommand( " GetServiceReceiptsAndPayments ")]
     public  class GetServiceReceiptsAndPayments
    {
        [DbParameter( " AccountID ")]
         public  int? AccountID {  getset; }

        [DbParameter( " StartTime ")]
         public DateTime? StartTime {  getset; }

        [DbParameter( " EndTime ")]
         public DateTime? EndTime {  getset; }

    }
}

  

生成的代碼包括Model和DataContext,其他均為框架實現.

這只是個開篇,框架還在完善中,如果有人感興趣,我會提供下載.以后我還會講到ORM中一些常見的概念,比如為什么要有DataContext,它有什么好處,如何跨數據庫,優雅的代碼是如何演變而來的.感謝你的閱讀!

 

注:好吧,鑒於有人有意見,從“ORM發展史”,改為“我的ORM發展史” 里面跨度的確有些大,因為下班了,不想寫,以后再補上吧
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM