Test Name: Nao_deve_permitir_nome_duplicados | |
Test FullName: Project.Test.FluentValidation.ModalidadeValidatorTest.Nao_deve_permitir_nome_duplicados | |
Test Source: {path}\Project.Test\FluentValidation\ModalidadeValidatorTest.cs : line 28 | |
Test Outcome: Failed | |
Test Duration: 0:00:00,4946356 | |
Result Message: | |
Test method Project.Test.FluentValidation.ModalidadeValidatorTest.Nao_deve_permitir_nome_duplicados threw exception: | |
System.ArgumentException: Expression of type 'System.Func`2[Project.Model.Modalidade,System.Int32]' cannot be used for return type 'System.Int32' | |
Result StackTrace: | |
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters) | |
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters) | |
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters) | |
at Project.Web.Validacoes.UniqueValidator`1.IsValid(PropertyValidatorContext context) in {path}\Validacoes\UniqueValidator.cs:line 39 | |
at FluentValidation.Validators.PropertyValidator.Validate(PropertyValidatorContext context) in {path}\PropertyValidator.cs:line 63 | |
at FluentValidation.Internal.PropertyRule.<Validate>d__c.MoveNext() in {path}\Internal\PropertyRule.cs:line 216 | |
at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext() | |
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) | |
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) | |
at FluentValidation.AbstractValidator`1.Validate(ValidationContext`1 context) in {path}\AbstractValidator.cs:line 83 | |
at FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate) in {path}\ValidatorTester.cs:line 46 | |
at Project.Test.FluentValidation.ModalidadeValidatorTest.Nao_deve_permitir_nome_duplicados() in {path}\ModalidadeValidatorTest.cs:line 36 | |
public static IRuleBuilderOptions<T, TElement> MustBeUnique<T, TElement, TEntity>(this IRuleBuilder<T, TElement> ruleBuilder | |
, Expression<Func<TEntity, int>> propertyId | |
, IRepository<TEntity> repository | |
) | |
where TEntity : class, IEntity | |
{ | |
return ruleBuilder.SetValidator(new UniqueValidator<TEntity>(propertyId, repository)); | |
} |
public class UniqueValidator<T> : PropertyValidator | |
where T : class, IEntity | |
{ | |
private readonly Expression<Func<T, int>> PropertyId; | |
private readonly IRepository<T> Repository; | |
public UniqueValidator(Expression<Func<T, int>> propertyId, IRepository<T> repository) | |
: base("{PropertyName} já existe!") | |
{ | |
PropertyId = propertyId; | |
Repository = repository; | |
} | |
protected override bool IsValid(PropertyValidatorContext context) | |
{ | |
// TODO: Not Work!! | |
// Read: https://fluentvalidation.codeplex.com/discussions/353331#post1050039 and http://stackoverflow.com/questions/16765086/dynamic-expression-for-filter-iqueryable | |
if (context.PropertyValue == null || string.IsNullOrWhiteSpace(context.PropertyValue.ToString())) | |
return true; | |
var currentId = Expression.Lambda<Func<int>>(PropertyId).Compile()(); // ERROR HERE | |
// From: http://msdn.microsoft.com/en-us/library/vstudio/bb882637.aspx, http://msdn.microsoft.com/en-us/library/bb397951.aspx | |
// Compose the expression tree that represents the parameter to the predicate. | |
// p => p.Id != currentId | |
ParameterExpression pId = Expression.Parameter(typeof(int), "Id"); | |
ConstantExpression cId = Expression.Constant(currentId, typeof(int)); | |
BinaryExpression notCurrent = Expression.NotEqual(pId, cId); | |
Expression<Func<int, bool>> NotCurrentExpr = | |
Expression.Lambda<Func<int, bool>>( | |
notCurrent, | |
new ParameterExpression[] { pId }); | |
// p.{PropertyName} == context.PropertyValue | |
ParameterExpression pUnique = Expression.Parameter(typeof(string), context.PropertyName); | |
ConstantExpression cUnique = Expression.Constant(context.PropertyValue, typeof(string)); | |
BinaryExpression checkUnique = Expression.Equal(pId, cId); | |
Expression<Func<string, bool>> CheckUniqueExp = | |
Expression.Lambda<Func<string, bool>>( | |
checkUnique, | |
new ParameterExpression[] { pUnique }); | |
var exp = Expression.And(NotCurrentExpr, CheckUniqueExp); | |
throw new NotImplementedException(); | |
/* | |
if (currentId > 0) | |
return Repository.All().Provider.CreateQuery(exp); // y(p => p.Id != currentId && p.{HowToGetPropertyByExpression?} == context.PropertyValue) | |
return Repository.All().Any(checkUnique); | |
*/ | |
} | |
} |
public class ModalidadeValidator : AbstractValidator<ModalidadeViewModel> | |
{ | |
public ModalidadeValidator(IXXRepository repositorio) | |
{ | |
RuleFor(p => p.Name) | |
.MustBeValidName() | |
.MustBeUnique(p => p.Id, repositorio); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment