2016-01-03 22 views
6

Tôi đang chuyển một dự án cũ sang ASP.NET 5 và Entity Framework 7. Tôi đã sử dụng phương pháp tiếp cận cơ sở dữ liệu đầu tiên (khung DNX) để tạo mô hình.Entity Framework 7 log kiểm toán

Các dự án cũ được dựa trên Entity Framework 4 và theo dõi kiểm toán được thực hiện bằng cách ghi đè các phương pháp SaveChanges của DbContext:

public override int SaveChanges(System.Data.Objects.SaveOptions options) 
{ 
    int? UserId = null; 
    if (System.Web.HttpContext.Current != null) 
     UserId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)) 
    { 
     Type EntityType = entry.Entity.GetType(); 

     PropertyInfo pCreated = EntityType.GetProperty("Created"); 
     PropertyInfo pCreatedById = EntityType.GetProperty("CreatedById"); 
     PropertyInfo pModified = EntityType.GetProperty("Modified"); 
     PropertyInfo pModifiedById = EntityType.GetProperty("ModifiedById"); 

     if (entry.State == EntityState.Added) 
     { 
      if (pCreated != null) 
       pCreated.SetValue(entry.Entity, DateTime.Now, new object[0]); 
      if (pCreatedById != null && UserId != null) 
       pCreatedById.SetValue(entry.Entity, UserId, new object[0]); 
     } 
     if (pModified != null) 
      pModified.SetValue(entry.Entity, DateTime.Now, new object[0]); 
     if (pModifiedById != null && UserId != null) 
      pModifiedById.SetValue(entry.Entity, UserId, new object[0]); 
     } 
    } 

    return base.SaveChanges(options); 
} 

Câu hỏi của tôi là, làm thế nào tôi có thể thực hiện điều này trong Entity Framework 7? Tôi có phải tiếp cận mã đầu tiên không?

+0

EF7 không được hoàn thành và không sẵn sàng cho sản xuất. Tôi sẽ đi cho EF6 và DbContext API đầu tiên. Vẫn còn nhiều mục trên backlog EF7 phải được thực hiện trước khi nó đủ trưởng thành. –

+0

Sự hiểu biết của tôi là bạn có thể thực hiện nó theo cùng một cách ... hoặc về cơ bản giống nhau. – Seabizkit

+0

Cá nhân bạn nên chuyển id người dùng vào một phương thức, thay vì tham chiếu System.Web trong một lớp dữ liệu liên quan. – Seabizkit

Trả lời

5

Về cơ bản bạn có hai cách để đạt được điều này:

Sử dụng ChangeTracker API (EF 6+):

Đây là cách chúng tôi hiện đang làm điều đó trong EF 6 và nó vẫn là hợp lệ và làm việc cho EF 7:

Trước tiên, bạn phải đảm bảo rằng các thực thể của bạn đang triển khai giao diện chung cho các trường kiểm toán:

public interface IAuditableEntity 
{ 
    int? CreatedById { get; set; } 

    DateTime Created { get; set; } 

    int? ModifiedById { get; set; } 

    DateTime Modified { get; set; } 
} 


Sau đó, bạn có thể ghi đè SaveChanges và cập nhật từng lĩnh vực tương đồng với giá trị kiểm toán:

public override int SaveChanges() 
{ 
    int? userId = null; 
    if (System.Web.HttpContext.Current != null) 
     userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    var modifiedEntries = ChangeTracker.Entries<IAuditableEntity>() 
      .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); 

    foreach (EntityEntry<IAuditableEntity> entry in modifiedEntries) 
    { 
     entry.Entity.ModifiedById = UserId; 
     entry.Entity.Modified = DateTime.Now; 

     if (entry.State == EntityState.Added) 
     { 
      entry.Entity.CreatedById = UserId; 
      entry.Entity.Created = DateTime.Now; 
     } 
    } 

    return base.SaveChanges(); 
} 


Sử dụng EF 7 mới "Shadow Properties" Tính năng:

Shadow properties là các thuộc tính không tồn tại trong lớp thực thể của bạn. Giá trị và trạng thái của các thuộc tính này được duy trì hoàn toàn trong Trình theo dõi thay đổi.

Nói cách khác, các cột kiểm tra sẽ không được hiển thị trên thực thể của bạn mà dường như là một lựa chọn tốt hơn so với tùy chọn ở trên nơi bạn phải đưa chúng vào thực thể của bạn.

Để triển khai thuộc tính bóng, trước tiên bạn phải định cấu hình chúng trên thực thể của mình. Hãy nói rằng ví dụ bạn có một đối tượng người dùng mà cần phải có một số cột kiểm toán:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>().Property<int>("CreatedById"); 

    modelBuilder.Entity<User>().Property<DateTime>("Created"); 

    modelBuilder.Entity<User>().Property<int>("ModifiedById"); 

    modelBuilder.Entity<User>().Property<DateTime>("Modified"); 
} 


Sau khi cấu hình, bây giờ bạn có thể truy cập chúng trên SaveChanges() ghi đè và cập nhật giá trị của họ cho phù hợp:

public override int SaveChanges() 
{ 
    int? userId = null; 
    if (System.Web.HttpContext.Current != null) 
     userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    var modifiedBidEntries = ChangeTracker.Entries<User>() 
     .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); 

    foreach (EntityEntry<User> entry in modifiedBidEntries) 
    { 
     entry.Property("Modified").CurrentValue = DateTime.UtcNow; 
     entry.Property("ModifiedById").CurrentValue = userId; 

     if (entry.State == EntityState.Added) 
     { 
      entry.Property("Created").CurrentValue = DateTime.UtcNow; 
      entry.Property("CreatedById").CurrentValue = userId; 
     } 
    } 

    return base.SaveChanges(); 
} 


Suy nghĩ cuối cùng:

Đối với việc thực hiện một cái gì đó giống như cột kiểm toán, tôi sẽ lấy Shadow Properties tiếp cận vì đây là những mối quan tâm cắt ngang và không nhất thiết thuộc về các đối tượng miền của tôi để chúng được triển khai theo cách này sẽ giữ cho các đối tượng miền của tôi đẹp và sạch sẽ.

+0

Bạn có thể giúp tôi kiểm tra mối quan hệ đã xóa và m-m bằng EF6 API không? –

0

Tôi đã làm việc trên thư viện có thể trợ giúp.

Hãy xem Audit.EntityFramework thư viện, nó chặn SaveChanges() và tương thích với phiên bản EF Core.