第一步:首先創建一個接口,用以暴露其操作的方法
public interface IOperate<TEntity>
{
List<TEntity> FindAll();
// TEntity FindByKey(object key);
int Add(TEntity entity);
int AddRange(IEnumerable<TEntity> entities);
int Delete(TEntity entity);
// int DeleteByKey(object key);
// int ChangeStatus(object key, object status);
int DeleteRange(IEnumerable<TEntity> entities);
int Update(TEntity entity);
// int Save(TEntity entity);
int ExecuteSql(string cmdStr, object[] paras);
List<TEntity> SqlQuery(string queryCmdStr, object[] paras);
}
第二部:實現接口,也就是用EF實現數據庫的操作
public class EfOperate<TEntity> : IOperate<TEntity> where TEntity : class
{
private VehicleCheckDBEntities _module;
private static readonly object LockHelper = new object();
public List<TEntity> SqlQuery(string queryCmdStr, object[] paras)
{
try
{
using (_module = new VehicleCheckDBEntities())
{
return paras == null ? _module.Database.SqlQuery<TEntity>(queryCmdStr).ToList() : _module.Database.SqlQuery<TEntity>(queryCmdStr, paras).ToList();
}
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
/// <summary>
/// 執行Sql語句
/// </summary>
/// <returns></returns>
public int ExecuteSql(string cmdStr, object[] paras)
{
/*
const string cmdStr = "update students set
name=@name where id<=@id";
var paras = new object[]
{
new SqlParameter("@name","哈哈"),
new SqlParameter("@id",3)
};
*/
DbContextTransaction transaction = null;
try
{
lock (LockHelper)
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
int rtnNUmber = paras == null
? _module.Database.ExecuteSqlCommand(cmdStr)
: _module.Database.ExecuteSqlCommand(cmdStr, paras);
_module.SaveChanges();
transaction.Commit();
return rtnNUmber;
}
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
}
protected DbSet<TEntity> DbSet
{
get
{
try
{
using (_module = new VehicleCheckDBEntities())
{
return _module.Set<TEntity>();
}
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
}
public List<TEntity> FindAll()
{
try
{
using (_module = new VehicleCheckDBEntities())
{
return _module.Set<TEntity>().ToList();
}
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
/// <summary>
/// 添加記錄
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int Add(TEntity entity)
{
#region 方法一 已測試
#if ceshi
using (module = new EfModule())
{
var entry = module.Entry(entity);
if (entry.State == EntityState.Detached)
{
entry.State = EntityState.Added;
}
return module.SaveChanges();
}
#endif
#endregion
#region 方法二 已測試
DbContextTransaction transaction = null;
try
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
_module.Set<TEntity>().Add(entity);
int rtnNumber = _module.SaveChanges();
transaction.Commit();
return rtnNumber;
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
#endregion
}
/// <summary>
/// 添加多條記錄
/// </summary>
/// <param name="entities"></param>
/// <returns></returns>
public int AddRange(IEnumerable<TEntity> entities)
{
DbContextTransaction transaction = null;
try
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
_module.Set<TEntity>().AddRange(entities);
int rtnNumber = _module.SaveChanges();
transaction.Commit();
return rtnNumber;
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
}
/// <summary>
/// 修改記錄
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int Update(TEntity entity)
{
//修改不像Add或Remove有直接的方法,所以必須更改記錄在上下文的狀態爲EntityState.Modified
DbContextTransaction transaction = null;
try
{
lock (LockHelper)
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
var entry = _module.Entry(entity);
if (entry.State == EntityState.Detached)
{
_module.Set<TEntity>().Attach(entity);
entry.State = EntityState.Modified;
}
int rtnNumber = _module.SaveChanges();
transaction.Commit();
return rtnNumber;
}
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
}
/// <summary>
/// 刪除記錄
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int Delete(TEntity entity)
{
#region 方法一 已測試 優點:使用任何類;不足之處是要手動更改記錄在上下文的狀態爲 EntityState.Deleted,與修改原理一樣
//using (module = new EfModule())
//{
// var entry = module.Entry(entity);
// if (entry.State == EntityState.Detached)
// {
// entry.State = EntityState.Deleted;
// }
// return module.SaveChanges();
//}
#endregion
#region 方法2 已測試 直接刪除,缺點: 只能使用Student類
//using (EfModule module = new EfModule())
//{
// var info = module.Students.Where(o => o.Id == 7).First();//若檢索到的對象是在using外面生成的,則會報錯
// module.Set<Student>().Remove(info); // module.Students.Remove(info); 兩者都可以
// return module.SaveChanges();
//}
#endregion
#region 方法3 已測試 直接刪除,優點:使用任何類,把記錄直接添加到上下文中,當Remove時會把狀態自動改爲Deleted
DbContextTransaction transaction = null;
try
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
//if (_module.Set<TEntity>().Any(o => o.Id == entity.Id))
//{
_module.Set<TEntity>().Attach(entity);
_module.Set<TEntity>().Remove(entity);
int rtnNumber = _module.SaveChanges();
transaction.Commit();
return rtnNumber;
//}
//return 0;
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
#endregion
}
/// <summary>
/// 刪除多條記錄
/// </summary>
/// <param name="entities"></param>
/// <returns></returns>
public int DeleteRange(IEnumerable<TEntity> entities)
{
DbContextTransaction transaction = null;
try
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
foreach (var entity in entities)
{
//if (_module.Set<TEntity>().Any(o => o.Id == entity.Id))
//{
var entry = _module.Entry(entity);
if (entry.State == EntityState.Detached)
{
entry.State = EntityState.Deleted;
}
//}
}
int rtnNumber = _module.SaveChanges();
transaction.Commit();
return rtnNumber;
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
}
}
第三步:創建對象
private static readonly IOperate<Device> DeviceOperate = new EfOperate<Device>();//創建操作表Device的對象
public static readonly IOperate<DeviceDeny> DeviceDenyOperate = new EfOperate<DeviceDeny>();//創建操作表DeviceDeny的對象
第四步:調用對象的方法
public int SaveDeviceDeny(DeviceDeny deviceDeny)
{
try
{
return deviceDeny.Id > 0 ? DeviceDenyOperate.Update(deviceDeny) : DeviceDenyOperate.Add(deviceDeny);
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
public int ChangeStatus(int key, int status)
{
const string cmdStr = "update device set
status=@status where id=@id";
var paras = new object[]
{
new SqlParameter("@status",status),
new SqlParameter("@id",key)
};
try
{
return DeviceOperate.ExecuteSql(cmdStr, paras);
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
public int DeleteDevice(int key)
{
string cmdStr =string.Format( "delete device where id={0}",key);
try
{
return DeviceOperate.ExecuteSql(cmdStr, null);
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
public int SaveDevice(Device device)
{
if (device == null)
return -1;
try
{
if (device.Id > 0)
{
const string cmdStr = " update device set UsedTimes=isnull(UsedTimes,0)+1,
LastUsingIp=@lastip,LastUsingDate=@lastdate ,LastUsingUserID=@userId where
id=@id ";
//var parameter = new object[]
// {
// new SqlParameter("@times", device.UsedTimes),
// new SqlParameter("@lastip", device.LastUsingIp),
// new SqlParameter("@lastdate", device.LastUsingDate),
// new SqlParameter("@userId", device.LastUsingUserID),
// new SqlParameter("@id", device.Id)
// };
//return DeviceOperate.ExecuteSql(cmdStr, parameter);
var parameter = new DbParameter[]
{
new SqlParameter("@times", device.UsedTimes),
new SqlParameter("@lastip", device.LastUsingIp),
new SqlParameter("@lastdate", device.LastUsingDate),
new SqlParameter("@userId", device.LastUsingUserID),
new SqlParameter("@id", device.Id)
};
return DbHelper.ExecuteNonQuery(CommandType.Text, cmdStr, parameter);
}
return DeviceOperate.Add(device);
}
catch (Exception error)
{
throw new Exception(error.Message);
}
}
實踐心得:
首先說一下不足之處,就是在修改方法的實現還是不盡人意,當併發調用的時候,程序會報錯,大體的意思是當實體類里加載了一條記錄時,修改的時候可能由於對這條數據加了鎖,無法進行修改;第二個錯誤就是實體對象模型connection已經關閉,無法對其進行操作,但是ADD方法與Delete方法不會出現此錯誤,所以我在Update方法中加了Lock,錯誤便不會出現。也即下面代碼:
/// <summary>
/// 修改記錄
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public int Update(TEntity entity)
{
//修改不像Add或Remove有直接的方法,所以必須更改記錄在上下文的狀態爲EntityState.Modified
DbContextTransaction transaction = null;
try
{
lock (LockHelper)
{
using (_module = new VehicleCheckDBEntities())
{
using (transaction = _module.Database.BeginTransaction())
{
var entry = _module.Entry(entity);
if (entry.State == EntityState.Detached)
{
_module.Set<TEntity>().Attach(entity);
entry.State = EntityState.Modified;
}
int rtnNumber = _module.SaveChanges();
transaction.Commit();
return rtnNumber;
}
}
}
}
catch (Exception error)
{
if (transaction != null)
transaction.Rollback();
throw new Exception(error.Message);
}
}
PS:另如果有更優化方案,望請指點,知識用來分享,從而才能在知識中得到樂趣!