在写数据库操作类时,需要对每张数据库表写基本的增删改查操作,及其繁琐且无聊。
故思考如何能简化,然后就有了下面的通用操作类。
使用要求:
1. 主键字段必须是 'id',不可为其它的。
2. 如需要假删,请对应修改假删的标识字段名(这里假设为'deleteFlag')
优点:
开发人员无须编写单表的增删改查方法。
缺点:
反射,以及大量的遍历;性能低下。
操作类源码如下:
使用方法如下:
万事OK!
故思考如何能简化,然后就有了下面的通用操作类。
使用要求:
1. 主键字段必须是 'id',不可为其它的。
2. 如需要假删,请对应修改假删的标识字段名(这里假设为'deleteFlag')
优点:
开发人员无须编写单表的增删改查方法。
缺点:
反射,以及大量的遍历;性能低下。
操作类源码如下:
/// <summary>
/// 数据库单表操作接口(无实际意义,规范 数据库单表操作 的接口)
/// </summary>
/// <typeparam name="Context">LinQ to SQL类</typeparam>
/// <typeparam name="T">映射表LinQ类</typeparam>
public abstract class ITableDAL<Context, T>
where Context : DataContext, new()
where T : class, INotifyPropertyChanging, INotifyPropertyChanged
{
protected const string GET_ENTITY_BY_ID_SQL = "SELECT * FROM {0} WHERE id = '{1}'";
/// <summary>
///
/// </summary>
protected Context db = new Context();
/// <summary>
/// 根据ID获取数据
/// </summary>
/// <param name="id">表ID</param>
/// <returns></returns>
public virtual T GetEntityById(int id)
{
try
{
return db.ExecuteQuery<T>((new StringBuilder()).AppendFormat(GET_ENTITY_BY_ID_SQL, typeof(T).Name, id).ToString()).Single();
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("数据库表'{0}'中不存在'{1}'为'{2}'的数据", typeof(T).Name, "id", id.ToString());
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 获取所有数据
/// </summary>
/// <returns></returns>
public virtual List<T> GetEntities()
{
try
{
Table<T> table = typeof(Context).GetProperty(typeof(T).Name).GetValue(db, null) as Table<T>;
return table.ToList();
}
catch
{
return new List<T>();
}
}
/// <summary>
/// 添加数据
/// </summary>
/// <param name="data">需添加的数据</param>
/// <returns></returns>
public virtual int AddEntity(T data)
{
try
{
Table<T> table = typeof(Context).GetProperty(typeof(T).Name).GetValue(db, null) as Table<T>;
table.InsertOnSubmit(data);
db.SubmitChanges();
return Convert.ToInt32(typeof(T).GetProperty("id").GetValue(data, null));
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("对数据库表'{0}'插入数据失败", typeof(T).Name);
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 修改数据
/// </summary>
/// <param name="data">需修改的数据</param>
/// <returns></returns>
public virtual bool EditEntity(T data)
{
try
{
Type t = typeof(T);
T editData = GetEntityById(Convert.ToInt32(t.GetProperty("id").GetValue(data, null)));
foreach (PropertyInfo property in t.GetProperties())
{
object newValue = property.GetValue(data, null);
bool isColumn = false;
foreach (object attr in property.GetCustomAttributes(false))
{
if (attr.GetType() == typeof(ColumnAttribute))
{
isColumn = true;
break;
}
}
if ((isColumn == true) && (newValue != null))
{
property.SetValue(editData, newValue, null);
}
}
db.SubmitChanges();
return true;
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("对数据库表'{0}'更新数据失败", typeof(T).Name);
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="id">需删除数据的ID</param>
/// <param name="isRealDelete">是否真删</param>
/// <returns></returns>
public virtual bool DeleteEntity(int id, bool isRealDelete)
{
try
{
T deleteData = GetEntityById(id);
if (isRealDelete)
{
Table<T> table = typeof(Context).GetProperty(typeof(T).Name).GetValue(db, null) as Table<T>;
table.DeleteOnSubmit(deleteData);
}
else
{
typeof(T).GetProperty("deleteFlag").SetValue(deleteData, 1, null);
}
db.SubmitChanges();
return true;
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("对数据库表'{0}'删除ID为'{1}'的数据失败", typeof(T).Name, id);
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 删除数据(默认真删)
/// </summary>
/// <param name="id">需删除数据的ID</param>
/// <returns></returns>
public bool DeleteEntity(int id)
{
return DeleteEntity(id, true);
}
}
/// 数据库单表操作接口(无实际意义,规范 数据库单表操作 的接口)
/// </summary>
/// <typeparam name="Context">LinQ to SQL类</typeparam>
/// <typeparam name="T">映射表LinQ类</typeparam>
public abstract class ITableDAL<Context, T>
where Context : DataContext, new()
where T : class, INotifyPropertyChanging, INotifyPropertyChanged
{
protected const string GET_ENTITY_BY_ID_SQL = "SELECT * FROM {0} WHERE id = '{1}'";
/// <summary>
///
/// </summary>
protected Context db = new Context();
/// <summary>
/// 根据ID获取数据
/// </summary>
/// <param name="id">表ID</param>
/// <returns></returns>
public virtual T GetEntityById(int id)
{
try
{
return db.ExecuteQuery<T>((new StringBuilder()).AppendFormat(GET_ENTITY_BY_ID_SQL, typeof(T).Name, id).ToString()).Single();
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("数据库表'{0}'中不存在'{1}'为'{2}'的数据", typeof(T).Name, "id", id.ToString());
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 获取所有数据
/// </summary>
/// <returns></returns>
public virtual List<T> GetEntities()
{
try
{
Table<T> table = typeof(Context).GetProperty(typeof(T).Name).GetValue(db, null) as Table<T>;
return table.ToList();
}
catch
{
return new List<T>();
}
}
/// <summary>
/// 添加数据
/// </summary>
/// <param name="data">需添加的数据</param>
/// <returns></returns>
public virtual int AddEntity(T data)
{
try
{
Table<T> table = typeof(Context).GetProperty(typeof(T).Name).GetValue(db, null) as Table<T>;
table.InsertOnSubmit(data);
db.SubmitChanges();
return Convert.ToInt32(typeof(T).GetProperty("id").GetValue(data, null));
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("对数据库表'{0}'插入数据失败", typeof(T).Name);
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 修改数据
/// </summary>
/// <param name="data">需修改的数据</param>
/// <returns></returns>
public virtual bool EditEntity(T data)
{
try
{
Type t = typeof(T);
T editData = GetEntityById(Convert.ToInt32(t.GetProperty("id").GetValue(data, null)));
foreach (PropertyInfo property in t.GetProperties())
{
object newValue = property.GetValue(data, null);
bool isColumn = false;
foreach (object attr in property.GetCustomAttributes(false))
{
if (attr.GetType() == typeof(ColumnAttribute))
{
isColumn = true;
break;
}
}
if ((isColumn == true) && (newValue != null))
{
property.SetValue(editData, newValue, null);
}
}
db.SubmitChanges();
return true;
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("对数据库表'{0}'更新数据失败", typeof(T).Name);
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="id">需删除数据的ID</param>
/// <param name="isRealDelete">是否真删</param>
/// <returns></returns>
public virtual bool DeleteEntity(int id, bool isRealDelete)
{
try
{
T deleteData = GetEntityById(id);
if (isRealDelete)
{
Table<T> table = typeof(Context).GetProperty(typeof(T).Name).GetValue(db, null) as Table<T>;
table.DeleteOnSubmit(deleteData);
}
else
{
typeof(T).GetProperty("deleteFlag").SetValue(deleteData, 1, null);
}
db.SubmitChanges();
return true;
}
catch (System.Exception ex)
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("对数据库表'{0}'删除ID为'{1}'的数据失败", typeof(T).Name, id);
throw new ApplicationException(errorMsg.ToString(), ex);
}
}
/// <summary>
/// 删除数据(默认真删)
/// </summary>
/// <param name="id">需删除数据的ID</param>
/// <returns></returns>
public bool DeleteEntity(int id)
{
return DeleteEntity(id, true);
}
}
使用方法如下:
//假设:
//LinQ映射类为 LinQDataContext
//数据库表名为 tbData
public class DataDAL : ITableDAL<LinQDataContext, tbData>
{
}
//LinQ映射类为 LinQDataContext
//数据库表名为 tbData
public class DataDAL : ITableDAL<LinQDataContext, tbData>
{
}
万事OK!