本业务逻辑是的生成也是基于单表的业务逻辑,使用了泛性的方法来对业务逻辑进行了抽象,大简化了重复代码的开发,并且如果有特殊的要求,还可以自定义业务逻辑类,从现有的类进行继承实现更复杂的操作。
首先在每个系统中,都会存在有日志系统和异常的处理和记录,首先来定义一个日志异常接口,如下:
public interface ILogException { #region 异常处理 void WriteException(EntityBase e); /// <summary> /// WriteException /// </summary> /// <param name="Ex">Exception</param> void WriteException(Exception Ex); /// <summary> /// WriteException /// </summary> /// <param name="modelName">模块名称</param> /// <param name="Ex">Exception</param> void WriteException(string modelName, Exception Ex); /// <summary> /// WriteException /// </summary> /// <param name="modelName">模块名称</param> /// <param name="message">Exception</param> void WriteException(string modelName, string message); /// <summary> /// 写操作日志 /// </summary> /// <param name="modelName">模块名称</param> /// <param name="OperaType">操作类型</param> /// <param name="OperaDesc">描述</param> /// <param name="OpResult"></param> void WriteOperationLogs(string modelName, string OperaType, string OperaDesc, bool OpResult); /// <summary> /// 调试信息接口 /// </summary> ILog Log { get; } #endregion }
public interface ILog { void InfoEnter(string message); void InfoExit(string message); void InfoFormatEnter(string FormatMessage, params object[] messages); void InfoFormatExit(string FormatMessage, params object[] messages); void Info(string message); void InfoFormat(string FormatMessage, params object[] messages); void Warn(string message); void WarnFromat(string FormatMessage, params object[] messages); void Error(string message); void ErrorFromat(string FormatMessage, params object[] messages); void Fatal(string message); void FatalFromat(string FormatMessage, params object[] messages); void Warn(string message, Exception e); void WarnFromat(string FormatMessage, Exception e, params object[] messages); void Error(string message, Exception e); void ErrorFromat(string FormatMessage, Exception e, params object[] messages); void Fatal(string message, Exception e); void FatalFromat(string FormatMessage, Exception e, params object[] messages); }
所有业务逻辑层都要继承此接口,这样在业务逻辑的操作中,就很容易的记录异常和日志信息,下面就给出通用业务逻辑接口:
public interface IBLL<T> : IBLLBase
where T : EntityBase
{
/// <summary>
/// 新增记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Add(T e, EntityBase LogInfo);
/// <summary>
/// 删除记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Delete(T e, EntityBase LogInfo);
/// <summary>
/// 删除记录,根据条件删除指定表的记录
/// 此方法有注入的可能,请预防
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Delete(T e, string WhereCondition, EntityBase LogInfo);
/// <summary>
/// 删除记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Deletes(T e, EntityBase LogInfo);
/// <summary>
/// 查询外键实体
/// </summary>
/// <param name="e">实体</param>
/// <param name="ForeignKeyName">外键名</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回实体</returns>
EntityBase GetEntityByForeignKey(T e, string ForeignKeyName, EntityBase LogInfo);
/// <summary>
/// 分页查询列表
/// </summary>
/// <param name="TableName">表名</param>
/// <param name="FieldNames">字段列表</param>
/// <param name="OrderName">排序名</param>
/// <param name="PageSize">分页大小</param>
/// <param name="PageIndex">页索引</param>
/// <param name="IsReCount">返回记录总数</param>
/// <param name="OrderType">排序类型</param>
/// <param name="strWhere"></param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回数据集</returns>
DataSet GetList(string TableName, string FieldNames, string OrderName, int PageSize, int PageIndex, bool IsReCount, bool OrderType, string strWhere, EntityBase LogInfo);
/// <summary>
/// 查询列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件</param>
/// <param name="OrderByExpression">排序</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回数据集</returns>
DataSet GetList(T e, string WhereCondition, string OrderByExpression, EntityBase LogInfo);
/// <summary>
/// 查询记录
/// </summary>
/// <param name="e"></param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Select(T e, EntityBase LogInfo);
/// <summary>
/// 查询外键列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="ForeignKeyName"></param>
/// <param name="LogInfo">日志信息</param>
/// <returns></returns>
DataSet SelectByForeignKey(T e, string ForeignKeyName, EntityBase LogInfo);
/// <summary>
/// 查询外键列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="ForeignKeyName">外键名称</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回列表</returns>
List<EntityBase> GetEntityListByForeignKey(T e, string ForeignKeyName, EntityBase LogInfo);
/// <summary>
/// 查询外键列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="ForeignKeyName">外键名称</param>
/// <returns>返回列表</returns>
List<EntityBase> GetEntityListByForeignKey(T e, string ForeignKeyName);
/// <summary>
/// 更新表
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">更新条件(SQL)</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Update(T e, string WhereCondition, EntityBase LogInfo);
/// <summary>
/// 更新记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Update(T e, EntityBase LogInfo);
/// <summary>
/// 更新记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="updateStatement">更新语句(SQL SET)</param>
/// <param name="WhereCondition">更新条件(where)</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返回true</returns>
void Update(T e, string updateStatement, string WhereCondition, EntityBase LogInfo);
/// <summary>
/// 新增记录
/// </summary>
/// <param name="e">实体</param>
/// <returns>成功返回true</returns>
void Add(T e);
/// <summary>
/// 删除记录
/// </summary>
/// <param name="e">实体</param>
/// <returns>成功返回true</returns>
void Delete(T e);
/// <summary>
/// 根据条件,删除记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件,SQL</param>
/// <returns>成功返回true</returns>
void Delete(T e, string WhereCondition);
/// <summary>
/// 删除记录
/// </summary>
/// <param name="e">实体</param>
/// <returns>成功返回true</returns>
void Deletes(T e);
/// <summary>
/// 查询外键实体
/// </summary>
/// <param name="e">实体</param>
/// <param name="ForeignKeyName">外键名</param>
/// <returns></returns>
EntityBase GetEntityByForeignKey(T e, string ForeignKeyName);
/// <summary>
/// 分页查询列表
/// </summary>
/// <param name="TableName">表名</param>
/// <param name="FieldNames">字段列表</param>
/// <param name="OrderName">排序名</param>
/// <param name="PageSize">分页大小</param>
/// <param name="PageIndex">页索引</param>
/// <param name="IsReCount">返回记录总数</param>
/// <param name="OrderType">排序类型</param>
/// <param name="strWhere">查询条件</param>
/// <returns>返回数据集</returns>
DataSet GetList(string TableName, string FieldNames, string OrderName, int PageSize, int PageIndex, bool IsReCount, bool OrderType, string strWhere);
/// <summary>
/// 查询列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件</param>
/// <param name="OrderByExpression">排序条件</param>
/// <returns></returns>
DataSet GetList(T e, string WhereCondition, string OrderByExpression);
/// <summary>
/// 查询记录
/// </summary>
/// <param name="e">实体</param>
/// <returns>成功返回true</returns>
void Select(T e);
/// <summary>
/// 查询外键实体
/// </summary>
/// <param name="e">实体</param>
/// <param name="ForeignKeyName">外键名</param>
/// <returns></returns>
DataSet SelectByForeignKey(T e, string ForeignKeyName);
/// <summary>
/// 根据条件更新记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件</param>
/// <returns>成功返回tru</returns>
void Update(T e, string WhereCondition);
/// <summary>
/// 更新记录
/// </summary>
/// <param name="e">实体</param>
/// <returns>成功返回true</returns>
void Update(T e);
/// <summary>
/// 根据更新语句和条件更新记录
/// </summary>
/// <param name="e">实体</param>
/// <param name="updateStatement"></param>
/// <param name="WhereCondition"></param>
/// <returns>成功返回true</returns>
void Update(T e, string updateStatement, string WhereCondition);
#region 通用存储过程执行方法,为子类准备
/// <summary>
/// 通用存储过程执行方法
/// </summary>
/// <param name="StroreName">存储过程名</param>
/// <param name="Parame">参数</param>
/// <returns>返回out参数</returns>
IDictionary<string, object> ExceStore(string StoreName, IList<Parameter> Parame);
/// <summary>
/// 通用执行方法,返回数据集
/// 不支持out参数
/// </summary>
/// <param name="StroreName">存储过程名</param>
/// <param name="Parame">参数</param>
/// <returns>返回数据集</returns>
DataSet ExceStoreGetDataSet(string StoreName, IList<Parameter> Parame);
/// <summary>
/// 存储过程名
/// </summary>
/// <param name="StoreName">存储过程名</param>
/// <param name="Parame">参数</param>
/// <returns>返回单个对象</returns>
object ExceStoreGetObject(string StoreName, IList<Parameter> Parame);
/// <summary>
/// 通用存储过程执行方法
/// </summary>
/// <param name="StroreName">存储过程名</param>
/// <param name="Parame">参数</param>
/// <param name="LogInfo">日志</param>
/// <returns>返回out参数</returns>
IDictionary<string, object> ExceStore(string StoreName, IList<Parameter> Parame, EntityBase LogInfo);
/// <summary>
/// 通用执行方法,返回数据集
/// 不支持out参数
/// </summary>
/// <param name="StroreName">存储过程名</param>
/// <param name="Parame">参数</param>
/// <param name="LogInfo">日志</param>
/// <returns>返回数据集</returns>
DataSet ExceStoreGetDataSet(string StoreName, IList<Parameter> Parame, EntityBase LogInfo);
/// <summary>
/// 通用执行存储过程方法
///
/// </summary>
/// <param name="StoreName">存储过程名</param>
/// <param name="Parame">参数</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回单个对象</returns>
object ExceStoreGetObject(string StoreName, IList<Parameter> Parame, EntityBase LogInfo);
#endregion
/// <summary>
/// 批量插入列表
/// </summary>
/// <param name="EntityList">实体列表</param>
/// <param name="LogInfo">日志信息</param>
/// <returns></returns>
void Add(IList<EntityBase> EntityList, EntityBase LogInfo);
/// <summary>
/// 批量插入列表
/// </summary>
/// <param name="EntityList">实体列表</param>
/// <returns></returns>
void Add(IList<EntityBase> EntityList);
/// <summary>
/// 查询列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件</param>
/// <param name="OrderByExpression">排序条件,支持多排序字段</param>
/// <returns>返回强类型列表</returns>
List<T> GetEntityList(T e, string WhereCondition, string OrderByExpression);
/// <summary>
/// 查询视图或表,返回强类型的对象
/// </summary>
/// <param name="e">实体</param>
/// <param name="OrderName">排序字段</param>
/// <param name="PageSize">单页大小</param>
/// <param name="PageIndex">页面编号</param>
/// <param name="IsReCount">是否返回记录总数</param>
/// <param name="OrderType">排序类型</param>
/// <param name="strWhere">过滤条件</param>
/// <param name="TotalCount">返回记录总数</param>
/// <returns>返回查询到的记录</returns>
List<T> GetEntityList(T e, string OrderName, int PageSize, int PageIndex, bool IsReCount, bool OrderType, string strWhere,ref int TotalCount);
/// <summary>
/// 查询列表
/// </summary>
/// <param name="e">实体</param>
/// <param name="WhereCondition">条件</param>
/// <param name="OrderByExpression">排序条件,支持多排序字段</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回强类型列表</returns>
List<T> GetEntityList(T e, string WhereCondition, string OrderByExpression, EntityBase LogInfo);
/// <summary>
/// 查询视图或表,返回强类型的对象
/// </summary>
/// <param name="e">实体</param>
/// <param name="OrderName">排序字段</param>
/// <param name="PageSize">单页大小</param>
/// <param name="PageIndex">页面编号</param>
/// <param name="IsReCount">是否返回记录总数</param>
/// <param name="OrderType">排序类型</param>
/// <param name="strWhere">过滤条件</param>
/// <param name="TotalCount">返回记录总数</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>返回查询到的记录</returns>
List<T> GetEntityList(T e, string OrderName, int PageSize, int PageIndex, bool IsReCount, bool OrderType, string strWhere, ref int TotalCount, EntityBase LogInfo);
/// <summary>
/// 批量更新成员,可以更新多个表
/// </summary>
/// <param name="EntityList">实体列表</param>
/// <param name="LogInfo">操作日志信息</param>
/// <returns></returns>
void Update(IList<EntityBase> EntityList, EntityBase LogInfo);
/// <summary>
/// 批量更新成员,可以更新多个表
/// </summary>
/// <param name="EntityList">实体列表</param>
/// <returns></returns>
void Update(IList<EntityBase> EntityList);
/// <summary>
/// 删除表记录
/// </summary>
/// <param name="EntityList">记录列表,可以是多个表的数据,在事务中执行</param>
/// <param name="LogInfo">日志信息</param>
/// <returns>成功返true</returns>
void Delete(IList<EntityBase> EntityList, EntityBase LogInfo);
/// <summary>
/// 删除表记录
/// </summary>
/// <param name="EntityList">记录列表,可以是多个表的数据,在事务中执行</param>
/// <returns>成功返true</returns>
void Delete(IList<EntityBase> EntityList);
}
上面接口了出现了EntityBase类型,这个是我上一篇中定义的一个抽象实体类,通过这种抽象,就可以实现一个业务类操作所有实体(不同表)。
为实现业务层对数据访问层的访问,我定义了一个工具类:
public static class DAHelper
{
/// <summary>
/// 默认的数据库连接字符串
/// </summary>
public static readonly string ConnectionStringKey = "ConnectionStringKey";
/// <summary>
/// 返回事务型的数据访问层接口
/// </summary>
/// <returns>数据访问层接口</returns>
public static IDABase GetIDABase()
{
return GetIDABase(true);
}
/// <summary>
/// 返回数据访问层接口对象
/// </summary>
/// <param name="IsTran">是启用事务</param>
/// <returns>数据层访问接口</returns>
public static IDABase GetIDABase(bool IsTran)
{
return GetIDABase(IsTran, ConnectionStringKey);
}
/// <summary>
/// 返回数据访问层接口对象
/// </summary>
/// <param name="IsTran">事务隔离级别</param>
/// <param name="ConnectionName">链接的名称</param>
/// <returns>数据层访问接口</returns>
public static IDABase GetIDABase(IsolationLevel IsolationLevel, string ConnectionName)
{
return new Dal.EnterpriseLibraryDABase(IsolationLevel, ConnectionName);
}
/// <summary>
/// 返回数据访问层接口对象
/// </summary>
/// <param name="IsTran">事务隔离级别</param>
/// <returns>数据层访问接口</returns>
public static IDABase GetIDABase(IsolationLevel IsolationLevel)
{
return GetIDABase(IsolationLevel, ConnectionStringKey);
}
/// <summary>
/// 返回数据访问层接口对象
/// </summary>
/// <param name="IsTran">是启用事务</param>
/// <param name="ConnectionName">链接的名称</param>
/// <returns>数据层访问接口</returns>
public static IDABase GetIDABase(bool IsTran, string ConnectionName)
{
return new Dal.EnterpriseLibraryDABase(IsTran, ConnectionName);
}
}
这样就可以很方便的开起一个事务,同时也对开人员对事务的了解可以简化。
下面来看一下,业务逻辑的具体实现(查询实体):
public void Select(T e, EntityBase LogInfo)
{
IDABase dalbase = null;
try
{
dalbase = GetIDABase();
if (!dalbase.Select(e))
{
throw new Exception("查询出错。");
}
else
{
if (LogInfo != null) dalbase.Insert(LogInfo);
dalbase.Commit();
}
}
catch (Exception ee)
{
if (dalbase != null)
dalbase.Rollback();
WriteException(ee);
throw new KMToolException(ee.Message, ee);
}
finally
{
if (dalbase != null)
dalbase.Close();
}
}
这样所有的方法都会出现一种统一的结构,如下:
public void 方法名(参数) { IDABase dalbase = null;//定义数据库访问对象 try { dalbase = GetIDABase();//获取数据库接口实例 //执行操作,同时,由于数据访问层有直接执行SQL语句的功能,这样就可以动态的改变当前的数据库,就可以进行多数据库的操作
dalbase.Commit(); //提交操作 } catch (Exception ee) { if (dalbase != null) dalbase.Rollback();//异常时回滚操作 WriteException(ee); throw new KMToolException(ee.Message, ee); } finally { if (dalbase != null) dalbase.Close();//关闭链接 } }
虽然数据访问层提供了对SQL语句执行的功能,但是不建议使用,另外从上面的获取数据访问层实例的是一个方法GetIDABase,包装一层的目的是为了便于单元测试进行mock,
实现如下:
/// <summary>
/// 返回事务型的数据访问层接口
/// </summary>
/// <returns>数据访问层接口</returns>
protected IDABase GetIDABase()
{
return GetIDABase(true);
}
/// <summary>
/// 返回数据访问层接口对象
/// </summary>
/// <param name="IsTran">是启用事务</param>
/// <returns>数据层访问接口</returns>
protected IDABase GetIDABase(bool IsTran)
{
return GetIDABase(IsTran,null);
}
/// <summary>
/// 返回数据访问层接口对象
/// </summary>
/// <param name="IsTran">是启用事务</param>
/// <param name="ConnectionName">链接的名称</param>
/// <returns>数据层访问接口</returns>
protected IDABase GetIDABase(bool IsTran, string ConnectionName)
{
if (_dal != null)
{
try
{
_dal.Close();
}
catch { }
return _dal;
}
return KMTool.Common.Dal.DAHelper.GetIDABase(IsTran, ConnectionName);
}
其实对单元测试进行mock的是一个方法:
private IDABase _dal = null; /// <summary> /// 测试注入专用方法 /// </summary> /// <param name="dal">注入的数据库访问类</param> protected void InitDal(IDABase dal) { if (dal == null) throw new ArgumentNullException("dal","此函数的参数dal不能允许为空."); _dal = dal; }
它是一个保护型的,在单元测试时,我们可以调用此方法进行注入。
这一篇就写到这里,下一篇来说一下,WebUI的生成。