2013-08-06 89 views
5

Tôi có một lớp phức tạp (xem ví dụ dưới đây) mà tôi lưu trong cơ sở dữ liệu Entity Framework Code First (V5). Vấn đề là nếu một FooClass được sử dụng trong dữ liệu FooAndOrBar được lưu vào cơ sở dữ liệu tôi muốn dừng mục nhập FooClass bị xóa. Bởi vì nó có thể là null sau đó kiểm tra khóa nước ngoài sẽ không dừng FooClass bị xóa vì vậy tôi phải kiểm tra bản thân mình.ValidateEntity trong Entity Framework không được gọi là Delete of entry

class FooClass { ... some properties } 

    class BarClass { ... some properties } 

    class FooAndOrBar 
    { 
     public int Id { get; set; } 
     public FooClass Foo { get; set; } 
     public BarClass Bar { get; set; } 
    } 

Vì vậy, sau khi thực hành tốt để xác thực mục nhập cắt qua nhiều mục cơ sở dữ liệu, tôi đã thêm thử nghiệm vào phương thức ValidateEntity của khung thực thể như được hiển thị bên dưới.

protected override DbEntityValidationResult ValidateEntity(
     DbEntityEntry entityEntry, IDictionary<object, object> items) 
    { 
     if (entityEntry.Entity is FooClass && 
      entityEntry.State == EntityState.Delete) 
     {    
      if (... entityEntry.Entity is used in DbContext.FooAndOrBars ...) 
       return new DbEntityValidationResult(... error ...); 
     } 

     return base.ValidateEntity(entityEntry, items); 

    } 

Vấn đề là ValidateEntity dường như không được gọi là xóa. Điều đó có ý nghĩa (tại sao xác nhận một cái gì đó bạn sẽ xóa) nhưng lá tôi với vấn đề của nơi tôi nên đặt kiểm tra? Tôi sử dụng một mẫu UnitOfWork/repository và có thể đặt một thử nghiệm trong đó, nhưng mùi đó.

Có ai khác gặp phải vấn đề này và giải quyết nó một cách sạch sẽ không? Phản hồi của bạn sẽ được đánh cao.

TRẢ LỜI TỪ Pawel (xem bên dưới).

@pawel đã chỉ ra rằng bạn có thể ghi đè lên ShouldValidateEntity để ValidateEntity được gọi cho các mục đã xóa. Dưới đây là một số mã ví dụ trong trường hợp ai đó thấy điều này hữu ích.

/// <summary> 
/// Override ShouldValidateEntity to cause deleted entities to be checked as well 
/// </summary> 
protected override bool ShouldValidateEntity(DbEntityEntry entityEntry) 
{ 
    if (entityEntry.State == EntityState.Deleted) 
     return true; 

    return base.ShouldValidateEntity(entityEntry); 
} 

Tôi thực sự đã kiểm tra chặt chẽ hơn tất cả các mục đã xóa bằng cách kiểm tra loại thực thể, nhưng đó chỉ là để cải thiện hiệu suất.

+0

Ban đầu nó làm cho tôi nghĩ về hành động xóa trong bộ điều khiển. – nocturns2

Trả lời

11

Theo mặc định, chỉ các thực thể đã sửa đổi và được thêm mới được xác thực. Điều này có thể được thay đổi bằng cách ghi đè phương thức DbContext.ShouldValidateEntity() để trả lại giá trị true cho các thực thể đã xóa.

+0

Xin chào @pawel. Đó là chính xác những gì tôi cần và nó hoạt động hoàn hảo. Tôi có thể đã thử nghiệm trong mã tôi có trong DbContext để theo dõi các thay đổi, nhưng đó là xác nhận hỗn hợp và theo dõi, mà không phải là một ý tưởng thông minh. Tôi đã bao gồm mã ví dụ trong câu trả lời của mình. –

+0

Vui vì nó hoạt động cho bạn và cảm ơn bạn đã thêm mã để hiển thị giải pháp. – Pawel