`

我的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发展史” 里面跨度的确有些大,因为下班了,不想写,以后再补上吧


分享到:
评论

相关推荐

    Java发展史概述

    Spring框架、Hibernate ORM和Struts等开源项目极大地推动了Java在企业级开发中的普及。此外,Java也广泛用于服务器端编程、游戏开发、物联网(IoT)和机器学习。 总结起来,Java的发展历程见证了从简单的Oak到全球...

    java 发展史

    随着时间的推移,Java社区不断发展,开源项目如Spring框架、Hibernate ORM等推动了Java在企业应用中的普及。2004年,JDK 5.0(也称为J2SE 5.0)引入了泛型、枚举等重要特性,进一步增强了Java的表达能力和类型安全性...

    第01章 Java开发入门 03 发展史体系与下载

    5. Java开源生态系统:包括Spring框架、Hibernate ORM、Maven构建工具等,丰富了Java的开发环境。 三、Java的下载与安装 1. 访问官网:首先,你需要访问Oracle的官方网站...

    dubbox介绍

    在这个阶段,简化数据库操作的数据访问框架(如ORM框架)是关键。 **垂直应用架构**:随着访问量的增长,单一应用通过增加服务器的方式提高处理能力的效果逐渐减弱。这时,将应用程序拆分为多个互不相关的子应用...

    最新版本最全的Spring的jar包

    Spring通过其Hibernate支持模块,使整合Hibernate变得更加简单,提供了事务管理、数据源配置以及ORM(对象关系映射)工具,降低了数据库操作的复杂性。 "dist"目录可能包含了打包好的Spring库文件,通常这些文件会...

    MLDN魔乐JAVAWEB课堂14_WEB安全实现及config对象

    - **SQL注入防御**:使用预编译语句、参数化查询或ORM框架(如Hibernate)来避免SQL注入漏洞。 2. **Spring Security**: - **Spring Security简介**:理解Spring Security框架的核心组件,如Filter Chain、...

    hibernata.jar1

    本文主要围绕标题提及的"hibernata.jar1",即Hibernate 3.2.2版本进行深入探讨,同时结合描述中的提示,我们会回顾这个非最新但依然具有价值的版本,并了解其在Hibernate发展史上的位置。 Hibernate 3.2.2是2007年...

    hibernate-release-4.0.0.CR5.zip

    本篇文章将深入探讨Hibernate 4.0.0 CR5版本,它是Hibernate发展史上一个重要的里程碑,带来了诸多改进和新特性。 首先,4.0.0版本标志着Hibernate的重大更新,它引入了对Java Persistence API (JPA) 2.0规范的全面...

    spring 3.11 的常用jar包以及源码jar

    这个版本在Spring框架的发展史上扮演着重要角色,引入了许多关键特性,提升了开发效率和应用性能。在这个压缩包中,包含了Spring 3.11的常用JAR包以及源码JAR,这对于开发者来说是一份宝贵的资源,可以方便地进行...

    spring-framework-4.0.3.RELEASE 源码

    4.0.3.RELEASE版本是Spring发展史上的一个重要里程碑,带来了许多改进和新特性。通过深入学习这个版本的源码,开发者可以更好地理解Spring的工作原理,从而提高编程效率,优化应用性能。 首先,Spring Framework的...

    spring.jar

    Spring框架2.5.6是Spring发展史上的一个重要里程碑,它在2.5系列中引入了许多关键改进和新特性,为当时的Java企业级应用提供了坚实的基础。以下是对这一版本的主要知识点的详述: 1. **依赖注入(Dependency ...

    史上最全的中国HL7标准的文档。涵盖了所有HL7的知识域

    《史上最全的中国HL7标准的文档》这一资源,显然包含了关于中国HL7标准的详尽信息,涵盖了所有的知识域。HL7 V2.4 CN,可能是文档集中的一部分,它代表了HL7的第2版第4次修订版,针对中国的特定需求进行了本地化和...

    spring-framework-3.1.0.RELEASE

    3.1.0.RELEASE版本是Spring发展史上的一个重要里程碑,它引入了许多新特性,优化了性能,并对已有功能进行了增强。下面我们将详细探讨Spring Framework 3.1.0.RELEASE的主要特点和关键知识点。 1. **依赖注入...

    史上最全JavaEE基础体系图解(xmind).xmind

    这个史上最全的JavaEE基础体系图解通过xmind文件形式,详细梳理了JavaEE学习的各个方面,旨在帮助初学者或开发者系统地理解和掌握JavaEE的核心概念。 1. **JavaEE概述** JavaEE是Sun Microsystems(现已被Oracle...

    hibernate3

    综上所述,这个"hibernate3"压缩包提供的3.2.5版本是Hibernate发展史上的一个重要版本,它包含了一整套用于Java开发的ORM解决方案,极大地提升了开发效率和代码质量。使用这些jar文件,开发者可以轻松地将Java对象与...

    Hibernate 3.2 中文参考

    此版本是Hibernate发展史上的一个重要里程碑,对提升Java应用程序的开发效率和数据访问层的性能有着显著贡献。 ### 学习目标 - **理解ORM原理**:深入理解对象关系映射的基本原理,包括如何将Java对象模型转换为...

    spring Framework 4.2.4

    这个版本是Spring框架发展史上的一个重要节点,引入了多项增强特性和优化,旨在提升开发效率和系统的可维护性。 首先,Spring Framework的核心特性包括依赖注入(Dependency Injection,DI),它允许开发者通过配置...

    spring2.5.5

    总结来说,Spring 2.5.5是Spring框架发展史上的一个重要里程碑,它包含了一系列增强的功能和改进,旨在提升开发者的效率和应用的灵活性。尽管这个版本已经相对过时,但对于理解Spring框架的基本概念和工作原理仍然...

    Ruby on Rails 3.2 Tutorial

    本教程覆盖了Rails 3.2版本,该版本在Rails发展史上占有重要地位,引入了许多改进和优化,包括更好的性能、更多的配置选项以及对CoffeeScript和jQuery等现代前端技术的支持。学习这个版本的Rails,可以让你对Web开发...

    spring2.5 mvc_ibatis2

    Spring 2.5版本是Spring发展史上的一个重要里程碑,它引入了许多新特性,使得开发更加高效。同时,iBatis作为一个轻量级的持久层框架,通过SQL映射文件将Java代码与数据库操作分离,提供了良好的可维护性。当这两个...

Global site tag (gtag.js) - Google Analytics