Mat*_*att 6 validation entity-framework-4.1 dbcontext
我正在尝试让EF 4.1与Repository,UnitOfWork一起工作,将实体与EF分离并进行验证.
我按照本指南将我的POCO实体从EF模型中分离出来,现在我按照本指南实现验证(使用IValidatableObject).
我的解决方案包括:
但我正在用验证打砖墙:
有人在这里有任何指示吗?我已经发布了下面的代码......
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Contacts.Entities.Contact.cs:
namespace Contacts.Entities
{
public partial class Contact
{
public string Name { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
Contacts.Validation.Contact.cs包含:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
从技术上讲,您可以引入具有显式实现的接口,如下所示:
在Contacts.Entities程序集中:
public interface IContactsDbContext
{
IQueryable<Contact> Contacts { get; }
// Not DbSet<Contact> because you don't want dependency on EF assembly
}
//...
public class Contact : IValidatableObject // No partial class anymore
{
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(
ValidationContext validationContext)
{
IContactsDbContext context =
validationContext.Items["Context"] as IContactsDbContext;
if (context.Contacts.Any<Contact>(c => c.Name == this.Name))
yield return new ValidationResult(
"Contact 'Name' is already in use.", new string[] { "Name" });
yield break;
}
// IValidatableObject, ValidationResult and ValidationContext is in
// System.ComponentModel.DataAnnotations.dll, so no dependency on EF
}
Run Code Online (Sandbox Code Playgroud)
在Contacts.Repository程序集(引用Contacts.Entities程序集)中:
public class ContactsDbContext : DbContext, IContactsDbContext
{
public DbSet<Contact> Contacts { get; set; }
IQueryable<Contact> IContactsDbContext.Contacts // explicit impl.
{
get { return Contacts; } // works because DbSet is an IQueryable
}
protected override DbEntityValidationResult ValidateEntity(
DbEntityEntry entityEntry, IDictionary<object, object> items)
{
items.Add("Context", this);
return base.ValidateEntity(entityEntry, items);
}
}
Run Code Online (Sandbox Code Playgroud)
Contacts.Validation程序集可以删除.
但是,我真的不喜欢这个解决方案.您的POCO - 通过该Validate方法 - 仍然依赖于存储库,如果接口与否.为了更好地分离关注点,我可能更愿意有一个单独的Validation类,它也可能对repo进行操作.或者,如果我要实现,IValidatableObject我可能只会进行仅依赖于模型对象属性的验证(例如"生产日期不得晚于发货日期"等等).嗯,这部分是品味问题.您链接的第二个示例并不真正关心问题的分离,因此您与第一个示例存在某种冲突.