.net - not - one to one relationship entity framework code first
¿Validar datos usando DataAnnotations con WPF y Entity Framework? (7)
¿Hay alguna forma de validar el uso de DataAnnotations en WPF y Entity Framework?
Creo que lo que falta en la respuesta de Craigs es cómo comprobar realmente si hay errores de validación. Este es un corredor de validación de DataAnnotation escrito por Steve Sanderson para aquellos que quieran ejecutar la verificación de validación en la capa deferente y luego en la presentación ( http://blog.codeville.net/category/xval/ , el código está en el proyecto de ejemplo):
public static IEnumerable<ErrorInfo> GetErrors(object instance)
{
var metadataAttrib = instance.GetType().GetCustomAttributes
(typeof(MetadataTypeAttribute), true).
OfType<MetadataTypeAttribute>().FirstOrDefault();
var buddyClassOrModelClass =
metadataAttrib != null ?
metadataAttrib.MetadataClassType :
instance.GetType();
var buddyClassProperties = TypeDescriptor.GetProperties
(buddyClassOrModelClass).Cast<PropertyDescriptor>();
var modelClassProperties = TypeDescriptor.GetProperties
(instance.GetType()).Cast<PropertyDescriptor>();
return from buddyProp in buddyClassProperties
join modelProp in modelClassProperties
on buddyProp.Name equals modelProp.Name
from attribute in buddyProp.Attributes.
OfType<ValidationAttribute>()
where !attribute.IsValid(modelProp.GetValue(instance))
select new ErrorInfo(buddyProp.Name,
attribute.FormatErrorMessage(string.Empty), instance);
}
No estoy familiarizado con WPF (no estoy seguro si hay alguna solución lista para usar), pero tal vez pueda usarla.
Además, hay algunos comentarios en su blog que en algunos casos no evalúa correctamente la regla de validación, pero nunca falló para mí.
En .NET 4, hay soporte de validación en Entity-Framework usando esta extensión, echa un vistazo a: http://blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata.aspx
No estoy seguro si usa DataAnnotations aunque.
ACTUALIZAR
Lo probé con VB.NET y no funcionó, creo que solo es compatible con proyectos de C #.
Es posible que le interese la aplicación de ejemplo BookLibrary del WPF Application Framework (WAF) . Hace exactamente lo que está pidiendo: utilizar DataAnnotations en WPF y Entity Framework.
He escrito un validador basado en Contributor que incluye un colaborador de validación de la anotación de datos y también verifica contra enlaces rotos (donde el usuario ha ingresado un tipo incorrecto)
http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/
Puede usar la clase DataAnnotations.Validator, como se describe aquí:
Pero si está utilizando una clase de "amigo" para los metadatos, debe registrar ese hecho antes de validar, como se describe aquí:
http://forums.silverlight.net/forums/p/149264/377212.aspx
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(typeof(myEntity),
typeof(myEntityMetadataClass)),
typeof(myEntity));
List<ValidationResult> results = new List<ValidationResult>();
ValidationContext context = new ValidationContext(myEntity, null, null)
bool valid = Validator.TryValidateObject(myEntity, context, results, true);
[Agregué lo siguiente para responder al comentario de Shimmy]
Escribí un método genérico para implementar la lógica anterior, para que cualquier objeto pueda llamarlo:
// If the class to be validated does not have a separate metadata class, pass
// the same type for both typeparams.
public static bool IsValid<T, U>(this T obj, ref Dictionary<string, string> errors)
{
//If metadata class type has been passed in that''s different from the class to be validated, register the association
if (typeof(T) != typeof(U))
{
TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(T), typeof(U)), typeof(T));
}
var validationContext = new ValidationContext(obj, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(obj, validationContext, validationResults, true);
if (validationResults.Count > 0 && errors == null)
errors = new Dictionary<string, string>(validationResults.Count);
foreach (var validationResult in validationResults)
{
errors.Add(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
if (validationResults.Count > 0)
return false;
else
return true;
}
En cada objeto que necesita validarse, agrego una llamada a este método:
[MetadataType(typeof(Employee.Metadata))]
public partial class Employee
{
private sealed class Metadata
{
[DisplayName("Email")]
[Email(ErrorMessage = "Please enter a valid email address.")]
public string EmailAddress { get; set; }
}
public bool IsValid(ref Dictionary<string, string> errors)
{
return this.IsValid<Employee, Metadata>(ref errors);
//If the Employee class didn''t have a buddy class,
//I''d just pass Employee twice:
//return this.IsValid<Employee, Employee>(ref errors);
}
}
Tuve la misma pregunta y encontré las siguientes ideas:
- Patrón de notificación
- Un puerto del control DataForm de Silverlight a WPF en CodePlex
Use una "clase de amigo". Número 4 en este cómo hacerlo .