65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.40/5 (3投票s)

2010年7月22日

Ms-PL

4分钟阅读

viewsIcon

23315

downloadIcon

114

本文详细介绍了如何使用 nHydrate 为 nHydrate DAL 和 Entity Framework DAL 添加审计框架。

概述

本文的目的是解释 nHydrate 中提供的审计功能。为数据库更改提供审计能力是许多系统的有用功能。因此,nHydrate 提供了一个实现,使实现审计解决方案变得轻松无痛。本文提供的示例将同时适用于传统的 nHydrate 数据访问层 (NHDAL) 和 nHydrate Entity Framework 数据访问层 (EFDAL)。

在阅读本文之前,您可能想查看以下文章

模型中有什么?

让我们开始查看模型中处理审计的属性。

审计字段名

第一个在 nHydrate 模型的数据库节点上。在这里,您可以确定要应用于审计字段的名称。这些字段将添加到指定要审计的实体的实体中。提供以下属性:CreatedByColumnNameCreatedDateColumnNameModifiedByColumnNameModifiedDateColumnName

index.001.png

表级审计设置

对于模型中的每个表,nHydrate 都提供了开启或关闭表级审计的功能。有三个设置需要考虑:

  • AllowCreateAudit - 这是一个真/假设置。当值为 true 时,表将带有两个列:created_by 和 created_date。这些字段在用户首次插入记录时设置。
  • AllowModifyAudit - 这是一个真/假设置。当值为 true 时,表将带有两个列:modified_by 和 modified_date。这些字段在用户每次更新记录时重置。
  • AllowAuditTracking - 这是一个真/假设置。当值为 true 时,它表示将创建一个新的数据库表来保存历史审计信息。

index.002.png

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);
  }
}

数据库中有什么?

在数据库中,当 AllowCreateAuditAllowModifyAudit 设置为 true 时,会向表中添加其他列。以客户表为例,我们看到存在 CreatedBy、CreatedOn、ModifiedByModifiedOn

接下来您会注意到的是,数据库模式中创建了一个新表。这个表就是存放审计记录的地方。这是因为在客户表设置中将 AllowAuditTracking 指定为 true

审计模型的数据库图

index.003.png

现在我们可以查看运行代码的结果。在数据库中,我们会注意到我们添加的两名客户的审计字段都有数据。这是在没有开发人员为每个存储的对象显式设置的情况下发生的。我们还将看到审计记录已在 __AUDIT__Customer 数据库表中建立。

客户和 __Audit__Customer 结果

index.004.png

杂项

  • 框架可以将 ModifiedDateCreatedDate__insertdate 设置为 UTC 或本地值。根据 UseUTCTime 设置,所有这些时间都将在数据库服务器上建立。
  • index.005.png

  • 手动设置 ModifiedDate 或 CreatedDate 将覆盖框架设置的值。
  • 数据库存储一个整数来标识审计操作。1 = 创建,2 = 更新,3 = 删除。
  • 类型为 textntextimage 的字段在审计表中不可用。
© . All rights reserved.