`

我的ORM发展史

 
阅读更多

之所以叫这个名字是因为我也在重复造轮子写了个ORM框架,从08年到现在,随着技术的累计对这其中的一些东西也有些领悟,恰巧今天的推荐头条也是关于ORM的,恰巧本人今天出差比较闲散,于是就忍不住要来献一下丑了.

起初,也就是08年,那会本人才刚从学校毕业,那会只知道PetShop比较出名,业界声誉较好,据说性能可以完胜Java,于是便学习了起来,从此以后在做所有项目必然出现DAL,BLL,Model这3层,由于大多项目根本没有跨数据库的需求,于是里面神马工厂模式,MySqlHelper,OracleHelper就全部丢掉了,唯一留下来的只有光荣的SqlHelper,那时SqlHelper的ExecuteDataReader,ExecuteNonequery,ExecuteDataset是屡试不爽啊.不过人总是懒惰和不安于现状的,后来还是觉得麻烦便萌生了写个工具去生成那些机械的DAL,BLL,Model,说干就干,便有了以下代码

复制代码
publicclasssUser
{
publicstringId {get;set;}
publicstringName{get;set;}
publicstringPassword{get;set;}
publicstringSex{get;set;}
publicDateTimeBirthday{get;set;}
}
复制代码

复制代码
publicclassUserDAL
{
pbblicvoidInsert(Useruser)
{
SqlParameter[]para=user.ToParameters();
SqlHelper.ExecNonequery(CommandType.StoreProcdure,"InsertUser",para);
}

publicvoidDelete(intid)
{
SqlParameter[]para=id.ToParameters();
SqlHelper.ExecNonequery(CommandType.StoreProcdure,"DeleteUserById",para);
}

publicvoidUpdate(Useruser)
{
SqlParameter[]para=user.ToParameters();
SqlHelper.ExecNonequery(CommandType.StoreProcdure,"UpdateUserById",para);
}

publicList<User>GetUserList()
{
List<User>userList=newList<User>();
DataReaderdr=SqlHelper.ExecDatareaderr(CommandType.StoreProcdure,"GetUserList",null);
returndr.ToList<User>();
}
}
复制代码

复制代码
publicclassUserBLL
{
privatereadonlyUserDAL_userDAL=newUserDAL();
pbblicvoidInsert(Useruser)
{
_userDAL.Insert(user);
}

publicvoidDelete(stringid)
{
_userDAL.Delete(id);
}

publicvoidUpdate(Useruser)
{
_userDAL.Update(user);
}

publicList<User>GetUserList()
{
return_userDAL.GetUserList();
}
}
复制代码

怎么样,很熟悉吧,不过以上代码都是临时敲的,是伪代码,实际提供的方法可能跟多不过结构跟这个大同小异.工具的原理便是从数据库读出表的信息来,生成存储过程和这3层代码,使用的时候只需要把生成的sql执行一遍,再拷贝代码文件到项目里就行了,如果刚建项目的话,甚至可以连项目文件一起生成,刚写好这个工具的时候的确感觉小有所成啦.

又过了一段时间,突然觉得好像还是很繁琐,比如数据库如果改了一个字段,我就要从新生成,从新执行sql,从新覆盖Model,DAL,BLL,更加致命的是,我没有办法去写一些更上层通用的方法,比如,我写一个表数据查看功能,我就需要在这个页面写很多case

假设这个页面接受参数tablename,我便需要这样写:

复制代码
switch(tablename)
{
case"User":
UserBLLbll=newUserBLL();
dataGrid.DataSource=bll.GetList();
break;
case"Product":
ProductBLLbll=newProductBLL();
dataGrid.DataSource=bll.GetList();
break;
case"Log":
LogBLLbll=newLogBLL();
dataGrid.DataSource=bll.GetList();
break;

}
复制代码

很明显同样的代码我需要写很多遍,先不说优不优雅,起码比较麻烦,没达到我们前面说的"人都是懒的"这一目的.我们要怎么改进呢,可能有人会说给BLL加上IBLL,那样可以把case里的dataGrid.DataSource=bll.GetList();这一句话给放到switch块外面.也就是这样

复制代码
switch(tablename)
{
IBLLbll;
case"User":
bll=newUserBLL();
break;
case"Product":
bll=newProductBLL();
break;
case"Log":
bll=newLogBLL();
break;
}
dataGrid.DataSource=bll.GetList();
复制代码

还有人可能会说用反射,可是这里我们先不说这点,当然这样可以解决问题,我们说上面一种方式,我们需要引入接口,定义IBLL,如下

复制代码
publicinterfaceIBLL<T>whereT:class
{
voidInsert(Tmodel);
voidDelete(stringid);
voidUpdate(Tmodel);
List<T>GetList();
}
复制代码

然后将BLL层这样改

publicclassUserBLL:IBLL<User>
{
//跟上面的UserBLL一样,此处略
}

好,收工.可是做好了这步,第一还是没解决,一改数据库就要去执行sql,覆盖DAL,BLL,Model,为了解决这些问题,我决定

1.将存储过程方式改为生成sql方式(要实现这一点我们就的定义很多特性(Attrbute))

2.将BLL层拿掉,因为在这里,没有意义,也就是大家都在说的未了分层而分层,层次显得太过僵硬做作.

3.只生成Model层,DAL定义泛型接口,所有实现走框架(现在才能算框架,以上其实就是代码生成器)

经过改进便有了如下代码:

Model
复制代码
//------------------------------------------------------------------------------
//<auto-generated>
//Thiscodegeneratedbythetool,donotproposetoamend
//Generationtime:2012/7/1618:01:46
//</auto-generated>
//------------------------------------------------------------------------------
usingSystem;
usingSystem.Data;
usingSystem.Runtime.Serialization;
usingXDbFramework;
usingSystem.Xml.Serialization;
usingSystem.Diagnostics;
usingSystem.CodeDom.Compiler;

namespaceModel
{
[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/")]
publicpartialclassModel_Admin
{

[Column(KeyType=KeyTypeEnum.PrimaryKey,ColumnName="AdminID",DbType=SqlDbType.Int,Index=0,Description="管理员编号")]
[DataMember(Order=0)]
publicint?AdminID{get;set;}


[Column(ColumnName="Passport",DbType=SqlDbType.VarChar,Index=1,Description="帐号")]
[DataMember(Order=1)]
publicstringPassport{get;set;}


[Column(ColumnName="Password",DbType=SqlDbType.VarChar,Index=2,Description="密码")]
[DataMember(Order=2)]
publicstringPassword{get;set;}


[Column(ColumnName="AddTime",DbType=SqlDbType.DateTime,Index=3,Description="操作时间")]
[DataMember(Order=3)]
publicDateTime?AddTime{get;set;}

}
}
复制代码

SqlAccessor
复制代码
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Data.Common;
usingSystem.Data.SqlClient;
usingSystem.Text;
usingXDbFramework.Linq;
usingSystem.Linq;

namespaceXDbFramework
{
publicclassSqlAccessor<T>:IDbExceuteAble,IDAL<T>whereT:class,new()
{
#regionprivatefileds
privateconststringInsertSqlFormat="INSERTINTO[{0}]({1})VALUES({2})";
privateconststringUpdateSqlFormat="UPDATE[{0}]SET{1}WHERE{2}";
privateconststringDeleteSqlFormat="DELETE[{0}]WHERE{1}";
privateconststringSelectFormat="SELECT{0}FROM{1}";
privateconststringSelectByWhereFormat="SELECT{0}FROM{1}WHERE{2}";
privateconststringSelectByWherePaginationFormat=@"WITHORDEREDRESULTSAS
(
SELECT{0},ROW_NUMBER()
OVER
(
ORDERBY{1}
)
ASROWNUMBER
FROM[{2}]WHERE{3}
)SELECT{4}FROMORDEREDRESULTSWHEREROWNUMBERBETWEEN{5}AND{6}
SELECTCOUNT(*)AS[COUNT]FROM[{7}]WHERE{8}
";
privatestaticreadonlyTableAttributeTableInfo=DalHelper<T>.GetTableInfo();
privateExecNonQuery_execNonQuery=(a,b,c)=>SqlHelper.ExecuteNonQuery(a,b,(SqlParameter[])c);
privateExecDataReader_execDataReader=(a,b,c)=>SqlHelper.ExecuteReader(a,b,(SqlParameter[])c);
privatereadonlyLinqQueryProvider<T>_linqQueryProvider;
#endregion

#regionprivatemethods
privateDbExecuteStateUpdateWithPredicate(Tt,Predicate<ColumnAttribute>predicate=null)
{
varsb=newStringBuilder();
varpk=DalHelper<T>.GetPrimaryKeyInfo(t);
varcolumList=DalHelper.GetTypeColumns(t);
varuColumns=newUpdateColumns();
foreach(ColumnAttributecolincolumList)
{
if(col.ColumnName!=pk.ColumnName&&(predicate==null||predicate(col)))
{
uColumns.Add(col.ColumnName,col.Value,col.ParameterType);
}
}
varcondition=newQuery(pk.ColumnName,CompareOperators.Equal,pk.Value,pk.OperatorType);
sb.AppendFormat(UpdateSqlFormat,TableInfo.TableName,uColumns.SqlString,condition.SqlString);
ExecNonQuery(CommandType.Text,sb.ToString(),null);
returnDbExecuteState.Succeed;
}


#endregion

#regionconstructor
publicSqlAccessor()
{
_linqQueryProvider=newLinqQueryProvider<T>(this);
}
#endregion

#regionpublicmethod
publicvoidInsert(Tt)
{
varsb=newStringBuilder();
varcolumns=newStringBuilder();
varcolumnsParameter=newStringBuilder();
varpk=DalHelper<T>.GetPrimaryKeyInfo();
varcolumList=DalHelper.GetTypeColumns(t);
varindex=0;
if(!TableInfo.GenreratePK)
{
columList.RemoveAll(c=>c.ColumnName==pk.ColumnName);
}
varparas=newSqlParameter[columList.Count];
foreach(ColumnAttributecolincolumList)
{
columns.AppendFormat("[{0}]",col.ColumnName);
columnsParameter.AppendFormat("@p_{0}",col.ColumnName);
if(index!=columList.Count-1)
{
columns.Append(",");
columnsParameter.Append(",");
}
paras[index]=newSqlParameter(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);
vardr=ExecDataReader(CommandType.Text,string.Format("Select*from[{0}]where[{1}]=IDENT_CURRENT('{2}')",TableInfo.TableName,pk.ColumnName,TableInfo.TableName),null);
varinsertT=DalHelper<T>.ToEntity(dr,true);
DalHelper<T>.SetPrimaryKeyValue(t,DalHelper<T>.GetPrimaryKeyValue(insertT));
}

publicDbExecuteStateDelete(objectid)
{
Tt=newT();
DalHelper<T>.SetPrimaryKeyValue(t,id);
returnDelete(t);

}

publicDbExecuteStateDelete(Tt)
{
varsb=newStringBuilder();
varpk=DalHelper<T>.GetPrimaryKeyInfo(t);
sb.AppendFormat(DeleteSqlFormat,TableInfo.TableName,string.Format("{0}=@p_{1}",pk.ColumnName,pk.ColumnName));
varpara=newSqlParameter(){ParameterName="@p_"+pk.ColumnName,Value=pk.Value,SqlDbType=(SqlDbType)pk.DbType};
ExecNonQuery(CommandType.Text,sb.ToString(),newSqlParameter[]{para});
returnDbExecuteState.Succeed;
}




publicDbExecuteStateUpdate(Tt)
{
returnUpdateWithPredicate(t);
}

publicDbExecuteStateUpdateIgnoreNull(Tt)
{
returnUpdateWithPredicate(t,col=>!col.Value.IsDBNull());
}

publicDbExecuteStateUpdateSingleColumn(Tt,stringcolumName,objectcolumValue)
{
DalHelper.SetModelValue(t,columName,columValue);
returnUpdateWithPredicate(t,col=>col.ColumnName==columName);
}

publicDbExecuteStateUpdateSingleColumn(objectid,stringcolumName,objectcolumValue)
{
Tt=newT();
DalHelper<T>.SetPrimaryKeyValue(t,id);
DalHelper.SetModelValue(t,columName,columValue);
returnUpdateWithPredicate(t,col=>col.ColumnName==columName);
}

publicboolExists(Tt)
{
varlst=GetList(t);
returnlst!=null&&lst.Count>0;
}

publiclongGetCount()
{
varsb=newStringBuilder();
sb.AppendFormat(SelectFormat,"count(*)",TableInfo.TableName);
vardr=ExecDataReader(CommandType.Text,sb.ToString(),null);
try
{
dr.Read();
returndr[0].ToString().AsInt();
}
finally
{
dr.Close();
dr.Dispose();
}

}

publicdecimalSum(Selector<T>selector,stringcolumn)
{
returnCacl(selector,string.Format("SUM({0})",column));
}

publicdecimalAvg(Selector<T>selector,stringcolumn)
{
returnCacl(selector,string.Format("AVG({0})",column));
}

privatelongCacl(Selector<T>selector,stringexpress)
{
varsb=newStringBuilder();
varcondition=selector.Condition;
sb.AppendFormat(SelectByWhereFormat,express,TableInfo.TableName,condition.SqlString);
vardr=ExecDataReader(CommandType.Text,sb.ToString(),null);
try
{
dr.Read();
returndr[0].ToString().AsInt();
}
finally
{
dr.Close();
dr.Dispose();
}
}

publiclongGetCount(Selector<T>selector)
{
if(selector==null)
returnGetCount();
returnCacl(selector,"count(*)");
}

publicobjectGetResult(Selector<T>selector)
{
returnGetResult<object>(selector);
}


publicTResultGetResult<TResult>(Selector<T>selector)
{
varsb=newStringBuilder();
varcondition=selector.Condition;
sb.AppendFormat(SelectByWhereFormat,selector.Colums,TableInfo.TableName,condition.SqlString);
vardr=ExecDataReader(CommandType.Text,sb.ToString(),null);
try
{
dr.Read();
return(TResult)dr[0];
}
finally
{
dr.Close();
dr.Dispose();
}
}

publicTGetSingle(Tt)
{
varlist=GetList(t);
if(list!=null&&list.Count>0)
returnlist[0];
returnnull;
}

publicTGetSingle(objectid)
{
vart=newT();
DalHelper<T>.SetPrimaryKeyValue(t,id);
returnGetSingle(t);
}

publicTGetSingle(Selector<T>selector)
{
varlist=GetList(selector);
if(list==null||list.Count<=0)
returnnull;
returnlist[0];
}

publicList<T>GetList()
{
varsb=newStringBuilder();
sb.AppendFormat(SelectFormat,"*",TableInfo.TableName);

vardr=ExecDataReader(CommandType.Text,sb.ToString(),null);
varlst=DalHelper<T>.ToList(dr,closeDataReader:true);
returnlst;
}

publicList<T>GetList(Paginationpagination)
{
returnGetList(newSelector<T>(){Pagination=pagination});
}



publicList<T>GetList(Selector<T>selector)
{
varpk=DalHelper<T>.GetPrimaryKeyInfo();
varcolumns=DalHelper.GetTypeColumns<T>();
varsb=newStringBuilder();
varcondition=selector.Condition;
stringwhere=condition==null?string.Empty:condition.SqlString;
where=string.IsNullOrEmpty(where)?"1=1":where;
varorderBy=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);
vardr=ExecDataReader(CommandType.Text,sb.ToString(),null);
try
{
varlst=DalHelper<T>.ToList(dr);
if(dr.NextResult())
{
dr.Read();
selector.Pagination.RecordCount=dr[0].ToString().AsInt();
}
returnlst;
}
finally
{
dr.Close();
dr.Dispose();
}
}

publicList<T>GetList(Tt)
{
varsb=newStringBuilder();
varcondition=newSelector<T>(t,null,null).Condition;
sb.AppendFormat(SelectByWhereFormat,"*",TableInfo.TableName,condition.SqlString);
vardr=ExecDataReader(CommandType.Text,sb.ToString(),null);
returnDalHelper<T>.ToList(dr,closeDataReader:true);
}

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

publicTSingle(System.Linq.Expressions.Expression<Func<T,bool>>predicate)
{
List<T>list=Where(predicate);
if(list!=null&&list.Count>0)
returnlist[0];
thrownewXDbException("未找到满足条件的项");
}

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

publicintCount(System.Linq.Expressions.Expression<Func<T,bool>>predicate)
{
return_linqQueryProvider.Count(predicate);
}

publicExecNonQueryExecNonQuery
{
get
{
return_execNonQuery;
}
set
{
if(value!=null)
_execNonQuery=value;
}
}
publicExecDataReaderExecDataReader
{
get
{
return_execDataReader;
}
set
{
if(value!=null)
_execDataReader=value;
}
}
#endregion

publicIEnumerator<T>GetEnumerator()
{
return_linqQueryProvider.GetEnumerator();
}

System.Collections.IEnumeratorSystem.Collections.IEnumerable.GetEnumerator()
{
return_linqQueryProvider.GetEnumerator();
}

publicTypeElementType
{
get{returntypeof(T);}
}

publicSystem.Linq.Expressions.ExpressionExpression
{
get{return_linqQueryProvider.Expression;}
}

publicIQueryProviderProvider
{
get{return_linqQueryProvider.Provider;}
}

}
}
复制代码

DataContext
复制代码
//------------------------------------------------------------------------------
//<auto-generated>
//Thiscodegeneratedbythetool,donotproposetoamend.
//Generationtime:2012/4/279:32:20
//</auto-generated>
//------------------------------------------------------------------------------

usingSystem;
usingExinSoft.Host.Model;
usingXDbFramework;

namespaceDALFactory
{
publicpartialclassDataContext:IDisposable
{

publicIDAL<Model_Account>Account
{
get
{
return_da.CreateDAL<Model_Account>();
}
}
publicIDAL<Model_AccountOfReceiptsAndPayments>AccountOfReceiptsAndPayments
{
get
{
return_da.CreateDAL<Model_AccountOfReceiptsAndPayments>();
}
}
publicIDAL<Model_AccountSnapshotRepository>AccountSnapshotRepository
{
get
{
return_da.CreateDAL<Model_AccountSnapshotRepository>();
}
}
publicIDAL<Model_Admin>Admin
{
get
{
return_da.CreateDAL<Model_Admin>();
}
}


}
}
复制代码

以上提供了核心类的实现方式,下面我们来看看调用方式,看是否优雅

框架实现的功能有,普通CRUD,存储过程执行,查询提供两种方式,即普通方式和Linq方式

普通方式:

复制代码
DataContext.Invoke(context=>
{
varselector=Selector<Model_Admin>
.NewQuery(m=>m.AdminID>=1)
.And(m=>m.AdminID<5)
.And(m=>m.AddTime>newDateTime(2010,1,1))
.And(m=>m.AddTime<newDateTime(2012,1,1))
.Page(1,10)
.Ascending(m=>m.AdminID);
varlist=context.Admin.GetList(selector);
});
复制代码

Linq方式:

DataContext.Invoke(context=>
{
varr=fromaincontext.Adminwherea.AdminID==1selecta;
varc=r.Count();
});

存储过程支持:

代码
复制代码
publicclassGetServiceReceiptsAndPaymentsResult
{
publicintServiceID{get;set;}
publicdecimal?sumMoney{get;set;}
}

[DbCommand("GetServiceReceiptsAndPayments")]
publicclassGetServiceReceiptsAndPayments
{
[DbParameter("AccountID")]
publicint?AccountID{get;set;}

[DbParameter("StartTime")]
publicDateTime?StartTime{get;set;}
[DbParameter("EndTime")]
publicDateTime?EndTime{get;set;}

}

using(varcontext=newDataContext())
{
varresult=context.SearchResultFromProcedure<GetServiceReceiptsAndPaymentsResult,GetServiceReceiptsAndPayments>(newGetServiceReceiptsAndPayments
{
AccountID=1,
StartTime=newDateTime(2010,1,1),
EndTime=newDateTime(2012,1,1)
});//传递参数并获取列表
Assert.AreNotEqual(result,null);
}

复制代码

更多:

调用方式
复制代码
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Linq;
usingExinSoft.Host.DALFactory;
usingExinSoft.Host.Model;
usingMicrosoft.VisualStudio.TestTools.UnitTesting;
usingXDbFramework;

namespaceXDBFrameworkText
{
[TestClass]
publicclassUnitTest1
{
[TestMethod]
publicvoidInsertTest()
{
stringpassport="x"+DateTime.Now.Ticks;
varadmin=newModel_Admin{AddTime=DateTime.Now,Passport=passport,Password="123456"};
using(varcontext=newDataContext())
{
context.Admin.Insert(admin);
Model_AdmininsertedAdmin=context.Admin.GetSingle(newModel_Admin{Passport=passport});
Assert.AreEqual(admin.Passport,insertedAdmin.Passport);
}
}

[TestMethod]
publicvoidUpdateTest()
{
using(varcontext=newDataContext())
{
Model_Adminadmin=context.Admin.GetSingle(newModel_Admin{AdminID=11});
admin.Password=""+DateTime.Now.Ticks;
context.Admin.UpdateSingleColumn(admin,"Password",admin.Password);

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

[TestMethod]
publicvoidDeleteTest()
{
using(varcontext=newDataContext())
{
varadmin=newModel_Admin{AdminID=17};

context.Admin.Delete(admin);

Model_Adminadmin1=context.Admin.GetSingle(newModel_Admin{AdminID=17});

Assert.AreEqual(admin1,null);
}
}

[TestMethod]
publicvoidGetSingleTest()
{
using(varcontext=newDataContext())
{
Model_Adminadmin=context.Admin.GetSingle(newModel_Admin{AdminID=11});

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

[TestMethod]
publicvoidGetListTest()
{
using(varcontext=newDataContext())
{
List<Model_Admin>adminList=context.Admin.GetList();
Assert.AreNotEqual(adminList.Count,0);
}
}


[TestMethod]
publicvoidWhereTest()
{
using(varcontext=newDataContext())
{
varadminList=context.Admin.Where(m=>m.AdminID==11).ToList();
Assert.AreEqual(adminList[0].AdminID,11);
}
}

[TestMethod]
publicvoidSingleTest()
{
using(varcontext=newDataContext())
{
Model_Adminadmin=context.Admin.Single(m=>m.AdminID==11);
Assert.AreEqual(admin.AdminID,11);
}
}


publicstaticreadonlystringBuyProduct_Code="1105";
[TestMethod]
publicvoidSingleTest2()
{
using(varcontext=newDataContext())
{
varserver=context.Services.Single(m=>m.ServiceCode==BuyProduct_Code);
Assert.AreEqual(server.ServiceID,10);
}
}

[TestMethod]
publicvoidSingleOrDefaultTest()
{
using(varcontext=newDataContext())
{
varaid=11;
Model_Adminadmin=context.Admin.SingleOrDefault(m=>m.AdminID==aid);
Assert.AreEqual(admin.AdminID,11);
}
}

[TestMethod]
publicvoidPageTest()
{
using(varcontext=newDataContext())
{
List<Model_Admin>adminList=context.Admin.GetList(newSelector<Model_Admin>
{
Pagination=newPagination
{
PageIndex=1,
PageSize=2
}
});
Assert.AreEqual(adminList.Count,2);
}
}

[TestMethod]
publicvoidSelectorTest()
{
using(varcontext=newDataContext())
{
varselector=newSelector<Model_Admin>
{
MinObj=newModel_Admin
{
AdminID=1
},
MaxObj=newModel_Admin
{
AdminID=11
},
Pagination=newPagination
{
PageIndex=1,
PageSize=2
}
};
List<Model_Admin>adminList=context.Admin.GetList(selector);
Assert.AreEqual(selector.Pagination.RecordCount,9);
}
}

[TestMethod]
publicvoidQueryTest()
{
DataContext.Invoke(context=>
{
varselector=Selector<Model_Admin>
.NewQuery(m=>m.AdminID>=1)
.And(m=>m.AdminID<5)
.And(m=>m.AddTime>newDateTime(2010,1,1))
.And(m=>m.AddTime<newDateTime(2012,1,1))
.Page(1,10)
.Ascending(m=>m.AdminID);
varlist=context.Admin.GetList(selector);
Assert.AreNotEqual(list,null);
});
}

[TestMethod]
publicvoidLinqTest1()
{
DataContext.Invoke(context=>
{
varr=fromaincontext.Adminwherea.AdminID==1selecta;
varc=r.Count();

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

[TestMethod]
publicvoidLinqTest2()
{
DataContext.Invoke(context=>
{
varr=fromaincontext.Adminwherea.AdminID==1selecta;
varlist=r.ToList();
Assert.AreNotEqual(list,null);
});
}

[TestMethod]
publicvoidLinqTest3()
{
DataContext.Invoke(context=>
{
varr=fromaincontext.Adminwherea.AdminID==1&&a.Passport=="admin"selecta;
varlist=r.ToList();
Assert.AreNotEqual(list,null);
});
}

[TestMethod]
publicvoidLinqTest4()
{
DataContext.Invoke(context=>
{
varr=fromaincontext.Adminwherea.AdminID==1||a.Passport.Contains("admin")||a.Password.StartsWith("123")||a.Password.EndsWith("456")selecta;
varlist=r.ToList();
Assert.AreNotEqual(list,null);
});
}

[TestMethod]
publicvoidLinqTest5()
{
DataContext.Invoke(context=>
{
varr=fromaincontext.AdminHasRight
wherea.AdminID==1
selecta;
varlist=r.ToList();
Assert.AreNotEqual(list,null);
});
}


[TestMethod]
publicvoidTransactionTest()
{
using(varcontext=newDataContext())
{
longcount=context.Admin.Count();
vara=DataContextStatic.Recharge.Count(s=>s.State==Convert.ToInt32(1));
stringpassport="x"+DateTime.Now.Ticks;
context.BeginTransaction();
try
{
context.Admin.Insert(newModel_Admin
{
Passport=passport,
Password="123456",
AddTime=DateTime.Now
});
context.Admin.Insert(newModel_Admin
{
Passport=passport+"_2",
Password="123456",
AddTime=DateTime.Now
});
context.CommitTransaction();
}
catch
{
context.RollbackTransaction();
}

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


[TestMethod]
publicvoidProcTest1()
{
using(varcontext=newDataContext())
{
context.ExecuteProcedure("ClearingAccount");
}
}

[TestMethod]
publicvoidProcTest2()
{
using(varcontext=newDataContext())
{
varresult=context.SearchResultFromProcedure<GetServiceReceiptsAndPaymentsResult,GetServiceReceiptsAndPayments>(newGetServiceReceiptsAndPayments
{
AccountID=1,
StartTime=newDateTime(2010,1,1),
EndTime=newDateTime(2012,1,1)
});
Assert.AreNotEqual(result,null);
}
}

publicvoidTestTmp()
{
varselector=Selector<Model_AirTicket>
.NewQuery(m=>m.OrderID=="123")
.Or(m=>m.UIdCard=="123");
varquery=Query<Model_AirTicket>
.Where(air=>air.AddTime>=newDateTime(2012,1,1))
.And(air=>air.AddTime<newDateTime(2012,12,31));
selector.Condition.Connect(query,LogicOperators.Or);

}



[TestMethod]
publicvoidTestTmp1()
{



varairticket=new
{
ShopID=1,
IdCard="456",
OrderId="",
StartTime=newDateTime(2012,1,1),
EndTime=newDateTime(2012,12,1)
};
vart=newModel_AirTicket(){ShopID=123};
varselector=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(DataContextcontext=newDataContext())
{
varlist=context.AirTicket.GetList(selector);
}

}


[TestMethod]
publicvoidTestTmp2()
{
varairticket=new
{
ShopID=1,
IdCard="",
OrderId="",
StartTime=newDateTime(2012,1,1),
EndTime=newDateTime(2012,12,1)
};

using(DataContextcontext=newDataContext())
{
varlist=fromaincontext.AirTicketwherea.ShopID==airticket.ShopIDselecta;
vart=list.ToList();
}
}

[TestMethod]
publicvoidTestCount()
{
varaa=1;
vara=DataContextStatic.Recharge.Count(s=>s.State==Convert.ToInt32(aa));
}
}

publicclassGetServiceReceiptsAndPaymentsResult
{
publicintServiceID{get;set;}
publicdecimal?sumMoney{get;set;}
}

[DbCommand("GetServiceReceiptsAndPayments")]
publicclassGetServiceReceiptsAndPayments
{
[DbParameter("AccountID")]
publicint?AccountID{get;set;}

[DbParameter("StartTime")]
publicDateTime?StartTime{get;set;}

[DbParameter("EndTime")]
publicDateTime?EndTime{get;set;}

}
}
复制代码

生成的代码包括Model和DataContext,其他均为框架实现.

这只是个开篇,框架还在完善中,如果有人感兴趣,我会提供下载.以后我还会讲到ORM中一些常见的概念,比如为什么要有DataContext,它有什么好处,如何跨数据库,优雅的代码是如何演变而来的.感谢你的阅读!

注:好吧,鉴于有人有意见,从“ORM发展史”,改为“我的ORM发展史” 里面跨度的确有些大,因为下班了,不想写,以后再补上吧


分享到:
评论

相关推荐

    我的 ORM 框架

    使用运算符重载,实现 ORM 框架里的 INSERT、UPDATE、DELETE 和 SELECT 语句动态生成。SELECT 语句支持 INNER JOIN、LEFT OUTER JOIN 和RIGHT OUTER JOIN 多表联合查询,但不支持同一表的联合查询。 代码中只实现了 ...

    ORM框架ORM框架ORM框架ORM框架

    能实现基本的数据库操作能实现基本的数据库操作

    SqliteORM,一个很好的Sqlite ORM框架

    Sqlite ORM 是一个简单的C#类,对Sqlite的操作进行了封装,主要功能包括:表定义、生成,访问,更新等,其中,支持,多表的连接操作,语法类似Linq语法,使用非常方便,附加了使用说明文档。 例如,添加记录操作为...

    ORM思想的深入学习ORM.zip

    这里面包括了Hibernate和MyBatis的实现ORM思想的原理,以及讲解了什么是ORM思想。仿照Hibernate自定义了一个简单的增删改查的ORM框架,还有测试代码。

    .NET ORM框架

    ORM框架 C#.NET ORM框架ORM框架 C#.NET ORM框架ORM框架 C#.NET ORM框架ORM框架 C#.NET ORM框架

    Elasticsearch​的ORM工具orm4es.zip

    orm4es是一个Elasticsearch的ORM工具,它可以生成简单的查询对象.它本身非常简单,也很容易使用;代码生成通过freemark完成,它会自动解析es index 的mapping设置,根据mapping生成与index对应的java Bean,使用生成...

    sqlite3的ORM框架

    简单易用的基于SQLite3的C++ ORM框架

    ORM映射与WEB的应用

    ORM映射与WEB的应用ORM映射与WEB的应用ORM映射与WEB的应用ORM映射与WEB的应用ORM映射与WEB的应用ORM映射与WEB的应用

    ORM对象关系映射

    ORM对象关系映射。。ORM对象关系映射。。太详细了。。最全的介绍。

    hsweb-easy-orm, 简单的orm工具,为动态表单而生.zip

    hsweb-easy-orm, 简单的orm工具,为动态表单而生

    spring-orm.jar

    spring-orm.jar

    系统架构+ORM+设计模式

    系统架构+ORM+设计模式 系统架构+ORM+设计模式

    K-ORM 自定义ORM工具

    工具简介:自己实现的简单的ORM工具,使用到的技术:JDBC+java反射机制。 简单的文档:rar解压后,DOC目录下:K-ORM.DOC

    SqlSugar ORM工具箱2.2.7z

    SqlSugar ORM工具箱2.2.7z

    Dos.ORM代码生成器

    Dos.ORM 代码生成器 实体生成器

    Dos.ORM Demo

    选择Dos.ORM的理由:  1.上手非常简单,0学习成本。使用方便,按照sql书写习惯编写C#代码。功能强大。  2.轻量级,只有一个dll文件(不到200KB),相比于EF,NHibernate这些重量级的ORM框架,实在是太小。  3....

    .net版ORM代码示例

    简单讲述orm使用,对于学习orm的很有帮助。

    Net下ORM框架概述

    Net下ORM框架概述,仅供参考,ORM是企业开放的热门技术

    经典 dao orm方法

    这是很经典的 dao orm 方法 魔乐技术2008的经典

    Sharp-ORM for Access 1.4

    Sharp-ORM 的支持 Access 的版本 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Sharp-ORM公开源码地址: http://download.csdn.net/source/336341 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Global site tag (gtag.js) - Google Analytics