I'm trying to get EF 4.1 working with Repository, UnitOfWork, separation of entities from EF and validation.
I followed this guide to get a nice separation of my POCO entities from the EF model and I'm now following this guide to implement validation (with IValidatableObject).
My solution consists of:
- Contacts.Repository [references EF and Contacts.Entities]:
- Contacts.edmx
- ContactsDbContext.cs
- Contacts.Entities [no references]:
- Contact.cs (Contacts.Entities.Contact partial class)
- Contacts.Validation [references Contacts.Entities and Contacts.Repository]
- Contact.cs (Contacts.Entities.Contact partial class)
But I'm hitting a brick wall with the validation:
- I cannot add validation logic to Contacts.Entities because it would cause a circular reference with Contacts.Repository (contact.Validate(...) needs to use ContactsDbContext). So I created a separate Contacts.Validation project.
- But, this means splitting the Contact class with partial classes to define Contact inside both Contacts.Entities and Contacts.Validation. The code no longer compiles because you can't define a partial class accross different assemblies.
Anyone got any pointers for me here? I've posted the code below...
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 contains:
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;
}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…