nHydrate DAL 和 Entity Framework 生成器的功能:第一部分 - 审计






3.40/5 (3投票s)
本文详细介绍了如何使用 nHydrate 为 nHydrate DAL 和 Entity Framework DAL 添加审计框架。
概述
本文的目的是解释 nHydrate 中提供的审计功能。为数据库更改提供审计能力是许多系统的有用功能。因此,nHydrate 提供了一个实现,使实现审计解决方案变得轻松无痛。本文提供的示例将同时适用于传统的 nHydrate 数据访问层 (NHDAL) 和 nHydrate Entity Framework 数据访问层 (EFDAL)。
在阅读本文之前,您可能想查看以下文章
模型中有什么?
让我们开始查看模型中处理审计的属性。
审计字段名
第一个在 nHydrate 模型的数据库节点上。在这里,您可以确定要应用于审计字段的名称。这些字段将添加到指定要审计的实体的实体中。提供以下属性:CreatedByColumnName
、CreatedDateColumnName
、ModifiedByColumnName
和 ModifiedDateColumnName
。
表级审计设置
对于模型中的每个表,nHydrate 都提供了开启或关闭表级审计的功能。有三个设置需要考虑:
- AllowCreateAudit - 这是一个真/假设置。当值为 true 时,表将带有两个列:created_by 和 created_date。这些字段在用户首次插入记录时设置。
- AllowModifyAudit - 这是一个真/假设置。当值为 true 时,表将带有两个列:modified_by 和 modified_date。这些字段在用户每次更新记录时重置。
- AllowAuditTracking - 这是一个真/假设置。当值为 true 时,它表示将创建一个新的数据库表来保存历史审计信息。
API 中有什么?
虽然 nHydrate DAL 和 Entity Framework 的生成框架略有不同,但它们都提供了实现审计功能的方法。
在下面的示例中,请特别注意以下几点:
- 首先,我们将确定执行更改的用户身份。这将允许框架在不需要开发人员为每个对象设置的情况下设置 modifiedby 和 createdby 列。
- 每个对象还添加了一个方便的方法,允许您回溯修改的历史记录。这样,就可以轻松地从 API 管理回滚或呈现对象历史记录。此示例中使用的方便方法会回溯所有审计记录(**未显示**)。此方法已重载以处理大型审计集。
instance.GetAuditRecords()
- 实例的所有审计记录。instance.GetAuditRecords(int pageOffset, int recordsPerPage)
- 实例的分页记录。instance.GetAuditRecords(int pageOffset, int recordsPerPage, DateTime? startDate, DateTime? endDate)
- 介于日期之间的实例的分页记录。recordsPerPage=0, pageOffset=0
:返回日期之间的所有记录。
nHydrateDAL - 示例
// Add a couple of customer objects. You will notice that during
// the creation of the customer collection we pass the modifier.
// We are also not setting modified_by, modified_on, created_by or created_on
// fields. These are implemented by the framework.
CustomerCollection customerCollection = new CustomerCollection("User14");
//Create a simple customer
//When persisted create record will be added to the audit table
Customer simpleCustomer = customerCollection.NewItem();
simpleCustomer.Name = "Simple Customer";
customerCollection.AddItem(simpleCustomer);
//Create another customer
//When persisted Create record will be added to the audit table
Customer customer = customerCollection.NewItem();
customer.Name = "Test Name 1";
customerCollection.AddItem(customer);
//Persist both customers they will both have the modifier or User14
customerCollection.Persist();
//Update the name. Updated record will be added to audit table
customer.Name = "Test Name 2";
customerCollection.Persist();
//Lets look at what the create a modify produced
//Retrieve customer from database that we just saved.
Customer auditedCustomer =
Customer.SelectUsingPK(customer.CustomerId, "User15");
//Write Audit Records. There will be two records.
//The first record will represent the creation.
//The second record will represent the modification.
foreach (CustomerAudit customerAudit in auditedCustomer.GetAuditRecords())
{
Console.WriteLine("AuditDate: " + customerAudit.AuditDate.ToString());
Console.WriteLine("AuditType: " + customerAudit.AuditType.ToString());
Console.WriteLine("CustomerId: " + customerAudit.CustomerId.ToString());
Console.WriteLine("Name: " + customerAudit.Name);
Console.WriteLine("ModifiedBy: " + customerAudit.ModifiedBy);
}
EFDAL - 示例
Guid createdCustomerID = Guid.Empty;
// Add a couple of customer objects.
// You will notice that during the creation of the ObjectContext
// (AuditExampleEntities). We provide a context startup
// object that specifies the modifying user
// We are also not setting modified_by, modified_on,
// created_by or created_on fields. These are
// implemented by the framework.
ContextStartup user14Startup = new ContextStartup("User14");
using (AuditExampleEntities context = new AuditExampleEntities(user14Startup))
{
//Create a simple customer
//When persisted create record will be added to the audit table
Customer simpleCustomer = new Customer();
simpleCustomer.Name = "Simple Customer";
context.AddItem(simpleCustomer);
//Create another customer
//When persisted Create record will be added to the audit table
Customer customer = new Customer();
customer.Name = "Test Name 1";
context.AddItem(customer);
//Persist both customers they will both have the modifier or User14
context.SaveChanges();
//Update the name. Updated record will be added to audit table
customer.Name = "Test Name 2";
context.SaveChanges();
createdCustomerID = customer.CustomerId;
}
//Lets look at what the create a modify produced
using (AuditExampleEntities context = new AuditExampleEntities(user14Startup))
{
//Retrieve customer from database that we just saved.
Customer customer = context.Customer.
Single(cust => cust.CustomerId == createdCustomerID);
//Write Audit Records. There will be two records.
//The first record will represent the creation.
//The second record will represent the modification.
foreach (CustomerAudit customerAudit in customer.GetAuditRecords())
{
Console.WriteLine("AuditDate: " + customerAudit.AuditDate.ToString());
Console.WriteLine("AuditType: " + customerAudit.AuditType.ToString());
Console.WriteLine("CustomerId: " + customerAudit.CustomerId.ToString());
Console.WriteLine("Name: " + customerAudit.Name);
Console.WriteLine("ModifiedBy: " + customerAudit.ModifiedBy);
}
}
数据库中有什么?
在数据库中,当 AllowCreateAudit
或 AllowModifyAudit
设置为 true
时,会向表中添加其他列。以客户表为例,我们看到存在 CreatedBy、CreatedOn、ModifiedBy 和 ModifiedOn。
接下来您会注意到的是,数据库模式中创建了一个新表。这个表就是存放审计记录的地方。这是因为在客户表设置中将 AllowAuditTracking
指定为 true
。
审计模型的数据库图
现在我们可以查看运行代码的结果。在数据库中,我们会注意到我们添加的两名客户的审计字段都有数据。这是在没有开发人员为每个存储的对象显式设置的情况下发生的。我们还将看到审计记录已在 __AUDIT__Customer 数据库表中建立。
客户和 __Audit__Customer 结果
杂项
- 框架可以将
ModifiedDate
、CreatedDate
和__insertdate
设置为 UTC 或本地值。根据UseUTCTime
设置,所有这些时间都将在数据库服务器上建立。 - 手动设置 ModifiedDate 或 CreatedDate 将覆盖框架设置的值。
- 数据库存储一个整数来标识审计操作。1 = 创建,2 = 更新,3 = 删除。
- 类型为
text
、ntext
或image
的字段在审计表中不可用。