使用数据库优先方法的 ChangeTracker 实现
ChangeTracker implementation with database first appraoch
我们公司刚开始使用 EF,如果 guidance/advise 解决我们的问题,我将不胜感激。在这个项目中,我们使用 EF 6、Visual Studio 2015、数据库优先方法和 RESTful 服务(这是一个 RESTful API 使用 JSON 而不是通用的API,我们只需要审计日志方法是通用的即可)。我们需要实施审计并正在调查使用 ChangeTracker 功能。这个想法是制作一个可以接受任何实体的通用方法。这是我们目前所拥有的;
轮班结束API控制器:
public class EndOfShiftsController : ApiController
{
private iSuiteEntities db = new iSuiteEntities();
// POST: api/EndOfShifts/post
[Route("api/EndOfShift/post")]
[ResponseType(typeof(EndOfShift))]
public async Task<IHttpActionResult> PostEndOfShift_Post(EndOfShiftDto endOfShift)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
EndOfShift endofshift = new EndOfShift()
{
EndOfShiftID = endOfShift.EndOfShiftID,
EndOfShiftDate = endOfShift.EndOfShiftDate,
EquipmentID = endOfShift.EquipmentID,
StartHours = endOfShift.StartHours,
EndHours = endOfShift.EndHours,
CreatedBy = endOfShift.CreatedBy,
CreateDate = DateTime.Now,
Active = true
};
try
{
if (!endOfShift.ToDelete)
{
if (EndOfShiftExists(endOfShift.EndOfShiftID))
{
var update = db.EndOfShifts.Find(endOfShift.EndOfShiftID);
update.EndOfShiftDate = endofshift.EndOfShiftDate;
update.EquipmentID = endofshift.EquipmentID;
update.StartHours = endOfShift.StartHours;
update.EndHours = endOfShift.EndHours;
db.Entry(update).State = EntityState.Modified;
//try calling the audit log method here/////////////////////////////////
AuditsController.GetAuditLogData(endofshift, endOfShift.EndOfShiftID, endOfShift.CreatedBy);
await db.SaveChangesAsync();
}
else
{
db.EndOfShifts.Add(endofshift);
await db.SaveChangesAsync();
}
}
else
{
EndOfShift delete = db.EndOfShifts.Find(endOfShift.EndOfShiftID);
if (delete == null)
{
return NotFound();
}
else
{
delete.Active = false;
db.Entry(delete).State = EntityState.Modified;
await db.SaveChangesAsync();
}
}
return Ok("Success");
}
catch(Exception ex)
{
return Ok(ex.Message);
}
//return CreatedAtRoute("DefaultApi", new { id = endOfShift.EndOfShiftID }, endOfShift);
}
通用审核日志记录方法类似于:
public class AuditsController : ApiController
{
private static iSuiteEntities dbContext = new iSuiteEntities();
private static iSuiteEntities db = new iSuiteEntities();
//write Audit log
public static async void GetAuditLogData<T>(T entity, int recID, int modByID) where T : new ()
{
try
{
var changeTrack = dbContext.ChangeTracker.Entries().Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified);
foreach (var entry in changeTrack)
{
if (entry.Entity != null)
{
string entityName = string.Empty;
string state = string.Empty;
switch (entry.State)
{
case EntityState.Modified:
entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;
state = entry.State.ToString();
foreach (string prop in entry.OriginalValues.PropertyNames)
{
object currentValue = entry.CurrentValues[prop];
object originalValue = entry.OriginalValues[prop];
if (!currentValue.Equals(originalValue))
{
Audit auditEntry = new Audit()
{
recordID = recID,
tableName = entityName,
fieldName = prop,
oldValue = Convert.ToString(originalValue),
editReason = "Update",
modifiedBy = modByID,
modifiedDate = DateTime.Now
};
db.Audits.Add(auditEntry);
await db.SaveChangesAsync();
}
}
break;
//data addition is not required to be logged/////
case EntityState.Deleted:
entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;
state = entry.State.ToString();
foreach (string prop in entry.OriginalValues.PropertyNames)
{
Audit auditEntry = new Audit()
{
recordID = recID,
tableName = entityName,
fieldName = prop,
oldValue = Convert.ToString(entry.OriginalValues[prop]),
editReason = "Delete",
modifiedBy = modByID,
modifiedDate = DateTime.Now
};
db.Audits.Add(auditEntry);
await db.SaveChangesAsync();
}
break;
default:
break;
}
}
}
}
catch (Exception ex)
{
//handle exception here....
}
}
对于我们的审计日志要求来说,这是一个可行的选择吗?代码还没有经过测试,所以我相信我们也需要一些编码方面的指导。如果这不是实现我们目标的可行选择,您能否推荐一个可以使用数据库优先方法实现的选项?提前致谢!!
在对谷歌搜索的内容采取不同的方法后,我们找到了 this link,这为我们提供了解决问题的方法。留在这里希望能为其他开发人员节省一些时间:-)
我们公司刚开始使用 EF,如果 guidance/advise 解决我们的问题,我将不胜感激。在这个项目中,我们使用 EF 6、Visual Studio 2015、数据库优先方法和 RESTful 服务(这是一个 RESTful API 使用 JSON 而不是通用的API,我们只需要审计日志方法是通用的即可)。我们需要实施审计并正在调查使用 ChangeTracker 功能。这个想法是制作一个可以接受任何实体的通用方法。这是我们目前所拥有的;
轮班结束API控制器:
public class EndOfShiftsController : ApiController
{
private iSuiteEntities db = new iSuiteEntities();
// POST: api/EndOfShifts/post
[Route("api/EndOfShift/post")]
[ResponseType(typeof(EndOfShift))]
public async Task<IHttpActionResult> PostEndOfShift_Post(EndOfShiftDto endOfShift)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
EndOfShift endofshift = new EndOfShift()
{
EndOfShiftID = endOfShift.EndOfShiftID,
EndOfShiftDate = endOfShift.EndOfShiftDate,
EquipmentID = endOfShift.EquipmentID,
StartHours = endOfShift.StartHours,
EndHours = endOfShift.EndHours,
CreatedBy = endOfShift.CreatedBy,
CreateDate = DateTime.Now,
Active = true
};
try
{
if (!endOfShift.ToDelete)
{
if (EndOfShiftExists(endOfShift.EndOfShiftID))
{
var update = db.EndOfShifts.Find(endOfShift.EndOfShiftID);
update.EndOfShiftDate = endofshift.EndOfShiftDate;
update.EquipmentID = endofshift.EquipmentID;
update.StartHours = endOfShift.StartHours;
update.EndHours = endOfShift.EndHours;
db.Entry(update).State = EntityState.Modified;
//try calling the audit log method here/////////////////////////////////
AuditsController.GetAuditLogData(endofshift, endOfShift.EndOfShiftID, endOfShift.CreatedBy);
await db.SaveChangesAsync();
}
else
{
db.EndOfShifts.Add(endofshift);
await db.SaveChangesAsync();
}
}
else
{
EndOfShift delete = db.EndOfShifts.Find(endOfShift.EndOfShiftID);
if (delete == null)
{
return NotFound();
}
else
{
delete.Active = false;
db.Entry(delete).State = EntityState.Modified;
await db.SaveChangesAsync();
}
}
return Ok("Success");
}
catch(Exception ex)
{
return Ok(ex.Message);
}
//return CreatedAtRoute("DefaultApi", new { id = endOfShift.EndOfShiftID }, endOfShift);
}
通用审核日志记录方法类似于:
public class AuditsController : ApiController
{
private static iSuiteEntities dbContext = new iSuiteEntities();
private static iSuiteEntities db = new iSuiteEntities();
//write Audit log
public static async void GetAuditLogData<T>(T entity, int recID, int modByID) where T : new ()
{
try
{
var changeTrack = dbContext.ChangeTracker.Entries().Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified);
foreach (var entry in changeTrack)
{
if (entry.Entity != null)
{
string entityName = string.Empty;
string state = string.Empty;
switch (entry.State)
{
case EntityState.Modified:
entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;
state = entry.State.ToString();
foreach (string prop in entry.OriginalValues.PropertyNames)
{
object currentValue = entry.CurrentValues[prop];
object originalValue = entry.OriginalValues[prop];
if (!currentValue.Equals(originalValue))
{
Audit auditEntry = new Audit()
{
recordID = recID,
tableName = entityName,
fieldName = prop,
oldValue = Convert.ToString(originalValue),
editReason = "Update",
modifiedBy = modByID,
modifiedDate = DateTime.Now
};
db.Audits.Add(auditEntry);
await db.SaveChangesAsync();
}
}
break;
//data addition is not required to be logged/////
case EntityState.Deleted:
entityName = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;
state = entry.State.ToString();
foreach (string prop in entry.OriginalValues.PropertyNames)
{
Audit auditEntry = new Audit()
{
recordID = recID,
tableName = entityName,
fieldName = prop,
oldValue = Convert.ToString(entry.OriginalValues[prop]),
editReason = "Delete",
modifiedBy = modByID,
modifiedDate = DateTime.Now
};
db.Audits.Add(auditEntry);
await db.SaveChangesAsync();
}
break;
default:
break;
}
}
}
}
catch (Exception ex)
{
//handle exception here....
}
}
对于我们的审计日志要求来说,这是一个可行的选择吗?代码还没有经过测试,所以我相信我们也需要一些编码方面的指导。如果这不是实现我们目标的可行选择,您能否推荐一个可以使用数据库优先方法实现的选项?提前致谢!!
在对谷歌搜索的内容采取不同的方法后,我们找到了 this link,这为我们提供了解决问题的方法。留在这里希望能为其他开发人员节省一些时间:-)