2015-08-04 23 views
6

Tôi đang cố gắng tìm ra cách thực hiện một phần cập nhật một cách trơn tru (về cơ bản là HTTP PATCH) của một thực thể, sử dụng Entity Framework 6.0, nhưng tôi đã stumped ở số ví dụ mà dường như không làm việc cho tôi (ngay cả những người không rõ ràng cho một phiên bản khác của EF).Cập nhật một phần thực thể trong EF6

Những gì tôi muốn thực hiện:

  • Thực thể được cập nhật mà không cần phải tải nó đầu tiên; tức là chỉ có một chuyến đi đến cơ sở dữ liệu Chỉ
  • các thuộc tính mà tôi chạm được cập nhật - những người khác còn lại như là

Gần nhất tôi đã nhận được gọn gàng được mô tả bởi this answer cho một câu hỏi rất giống nhau, và minh họa theo các mã sau:

public async Task UpdateMyEntity(int id, int? updatedProperty, string otherProperty) 
{ 
    using (var context = new MyDbContext()) 
    { 
     var entity = new MyEntity { Id = id }; 
     context.MyEntities.Attach(entity); 

     if (updatedProperty != null) { entity.Property = updatedProperty.Value; } 
     if (!string.IsNullOrEmpty(otherProperty) { entity.OtherProperty = otherProperty; } 

     await context.SaveChangesAsync(); 
    } 
} 

Bây giờ, điều này làm việc cho các thực thể đơn giản, nhưng tôi nhận được các yêu cầu xác thực và quan hệ không được cập nhật và do đó không có trong thực thể được đính kèm . Như đã nói, tôi chỉ muốn bỏ qua những điều đó.

Tôi đã sửa lỗi và xác minh rằng context.Entry(entity).Property(e => e.Property).IsModified thay đổi thành true khi dòng đó chạy và tất cả thuộc tính tôi chưa bao giờ chạm vẫn trả lại false để kiểm tra tương tự, vì vậy tôi nghĩ EF có thể xử lý việc này.

Có thể giải quyết vấn đề này theo hai ràng buộc ở trên không? Làm sao?


Cập nhật:

Với LSU.Net 's answer Tôi hiểu phần nào những gì tôi phải làm, nhưng nó không hoạt động đầy đủ. Logic không thành công cho các thuộc tính tham chiếu.

Hãy xem xét các mô hình miền sau:

public class MyEntity 
{ 
    public int Id { get; set; } 
    public int Property { get; set; } 
    [Required] 
    public string OtherProperty { get; set; } 
    [Required] 
    public OtherEntity Related { get; set; } 
} 

public class OtherEntity 
{ 
    public int Id { get; set; } 
    public string SomeProperty { get; set; } 
} 

Bây giờ, nếu tôi cố gắng cập nhật một MyEntity, tôi thực hiện như sau:

var entity = new MyEntity { Id = 123 }; // an entity with this id exists in db 
context.MyEntities.Attach(entity); 

if (updatedProperty != null) { entity.Property = updatedProperty.Value; } 

await context.SaveChangesAsync(); 

Trong phương pháp xác nhận tùy chỉnh của tôi, ghi đè như trong the answer below, lỗi xác thực trên thuộc tính bắt buộc OtherProperty được xóa chính xác vì nó không bị sửa đổi. Tuy nhiên, tôi vẫn gặp lỗi xác thực trên thuộc tính Related, vì entityEntry.Member("Related") is DbReferenceEntry, không phải DbPropertyEntry và do đó lỗi xác thực không được đánh dấu là lỗi giả.

Tôi đã thử thêm một mệnh đề tương tự, riêng biệt để xử lý các thuộc tính tham chiếu, nhưng entityEntry dường như không đánh dấu những thay đổi đó; với relation = member as DbReferenceEntry, relation không có bất cứ điều gì để chỉ ra rằng mối quan hệ được thay đổi.

Tôi có thể kiểm tra lỗi sai trong trường hợp này là gì? Có bất kỳ trường hợp nào khác mà tôi cần phải xử lý đặc biệt (ví dụ như một mối quan hệ một-nhiều) không?

Trả lời

2

Entity Framework validation with partial updates

@Shimmy đã viết một số mã vào đây để bỏ qua các logic xác nhận đối với tài sản cố định. Điều đó có thể làm việc cho bạn.

protected override DbEntityValidationResult ValidateEntity(
    DbEntityEntry entityEntry, 
    IDictionary<object, object> items) 
{ 
    var result = base.ValidateEntity(entityEntry, items); 
    var falseErrors = result.ValidationErrors 
    .Where(error => 
    { 
     var member = entityEntry.Member(error.PropertyName); 
     var property = member as DbPropertyEntry; 
     if (property != null) 
     return !property.IsModified; 
     else 
     return false;//not false err; 
    }); 

    foreach (var error in falseErrors.ToArray()) 
    result.ValidationErrors.Remove(error); 
    return result; 
} 
+0

Điều này thật tuyệt, nhưng vẫn không xóa được lỗi xác thực cho thuộc tính tham chiếu chưa được chạm. Tôi sẽ cập nhật OP để hiển thị trường hợp sử dụng. –

+0

Vui lòng xem cập nhật của tôi :) Mọi ý tưởng khác được chào đón nhiều nhất! –

Các vấn đề liên quan