Tôi đang cố gắng để có được EF 4.1 làm việc với Repository, UnitOfWork, tách các thực thể khỏi EF và xác thực.Entity Framework IValidatableObject tham chiếu DbContext
Tôi theo dõi this hướng dẫn để có được sự tách biệt tốt đẹp của các thực thể POCO của tôi từ mô hình EF và giờ tôi đang theo dõi hướng dẫn this để triển khai xác thực (với IValidatableObject).
giải pháp của tôi bao gồm:
- Contacts.Repository [tài liệu tham khảo EF và Contacts.Entities]:
- Contacts.edmx
- ContactsDbContext.cs
- Contacts.Entities [không có tham chiếu]:
- Contact.cs (Contacts.Entities.Contact phần lớp)
- Contacts.Validation [tài liệu tham khảo Contacts.Entities và Contacts.Repository]
- Contact.cs (Contacts.Entities.Contact partial class)
Nhưng tôi đánh một bức tường gạch với xác nhận:
- Tôi không thể thêm logic xác nhận vào Contacts.Entities vì nó sẽ gây ra tham chiếu vòng tròn với Contacts.Repository (contact.Validate (...) cần sử dụng ContactsDbContext). Vì vậy, tôi đã tạo một dự án Contacts.Validation riêng biệt.
- Tuy nhiên, điều này có nghĩa là tách lớp Liên hệ với các lớp một phần để xác định Liên hệ trong cả Contacts.Entities và Contacts.Validation. Mã không còn biên dịch vì bạn không thể định nghĩa một lớp một phần trên các assembly khác nhau.
Bất kỳ ai cũng có bất kỳ gợi ý nào cho tôi ở đây? Tôi đã đăng mã dưới đây ...
Contacts.Repository.ContactsDbContext.cs:
namespace Contacts.Repository
{
public partial class ContactsDbContext : DbContext
{
public DbSet<Contact> Contacts { get; set; }
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
items.Add("Context", this);
return base.ValidateEntity(entityEntry, items);
}
}
}
Contacts.Entities.Contact.cs:
namespace Contacts.Entities
{
public partial class Contact
{
public string Name { get; set; }
}
}
Contacts.Validation.Contact. cs chứa:
namespace Contacts.Entities
{
public partial class Contact : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
ContactsDbContext contacts = (ContactsDbContext)validationContext.Items["Context"];
//Check if Contact already exists with the same Name
if (contacts.Any<Contact>(c => c.Name == this.Name))
yield return new ValidationResult("Contact 'Name' is already in use.", new string[] { "Name" });
yield break;
}
}
Cảm ơn. - đó là một bước gần hơn. Tôi đồng ý, tôi muốn chia tách nhiều mối quan tâm hơn. Làm thế nào bạn thường tách ra Xác nhận từ Kho lưu trữ (bất kể EF)? Tôi có một mẫu xác nhận và Repository tốt cho phép tách hoàn toàn ... nhưng sau đó bạn có vấn đề mà người gọi có thể không gọi Validate trước khi gọi Save on the Repository. NB - bây giờ tôi đang phải đối mặt với tham chiếu khung thực thể trong người gọi vì xác nhận sẽ nâng cao một loại System.Data.Entity.Validation.DbEntityValidationException. Tôi thấy đây là một cuộc chiến khó chịu chống lại EF !!! – Matt
@Matt: Tôi không có sự tách biệt rõ ràng giữa xác thực và repo. Việc xác thực rằng một trường cụ thể phải là duy nhất là từ quan điểm của tôi không phải là xác nhận hợp lệ trên cấp thực thể. Nó cũng có thể được coi như là một xác nhận của repo (repo sẽ trở thành không hợp lệ * nếu * tôi muốn chèn một thực thể có cùng tên). Thông thường tôi truy cập repos của tôi thông qua các lớp học dịch vụ và ở đó tôi làm một "kiểm tra" trước khi tôi chèn nếu đã có một thực thể có cùng tên. Không phải xác thực được tách biệt rõ ràng. Nó có thể trở nên dễ dàng hơn và sạch hơn khi EF cung cấp tính năng "Unique Constraints" được đề cập trong bài đăng blog thứ hai. – Slauma
Tôi đang sử dụng DataAnnotation để cung cấp xác thực cấp thực thể. Tôi đồng ý kiểm tra tính duy nhất là một mức độ xác nhận khác và nó không thực sự là trên thực thể. TBH, tôi cảm thấy như EF đang ép tôi xuống con đường này. Tôi sẽ xem xét di chuyển nó vào kho lưu trữ. Cảm ơn bạn đã giúp đỡ. – Matt