2009-05-13 4 views
0

참고로 : Creating a ValidationAttribute to ensure unique column values.
ValidationAttribute 돌아 오는

좋아요 ...의 질문 프레이밍 해보자 : 그것은 DataContext에 확장 메서드가있어

static TEntity Get<TEntity, TKey>(this DataContext ctx, TKey key) where TEntity : class 
    { 
     var table = ctx.GetTable<TEntity>(); 
     var pkProp = (from member in ctx.Mapping.GetMetaType(typeof(TEntity)).DataMembers 
         where member.IsPrimaryKey 
         select member.Member).Single(); 
     ParameterExpression param = Expression.Parameter(typeof(TEntity), "x"); 
     MemberExpression memberExp; 
     switch (pkProp.MemberType) 
     { 
      case MemberTypes.Field: memberExp = Expression.Field(param, (FieldInfo)pkProp); break; 
      case MemberTypes.Property: memberExp = Expression.Property(param, (PropertyInfo)pkProp); break; 
      default: throw new NotSupportedException("Invalid primary key member: " + pkProp.Name); 
     } 
     Expression body = Expression.Equal(
     memberExp, Expression.Constant(key, typeof(TKey))); 
     var predicate = Expression.Lambda<Func<TEntity, bool>>(body, param); 
     return table.Single(predicate); 
    } 

: 나는이 코드를 찢어 here에서

을 필요한 물건.

public override bool IsValid(object value) 
     SomeDataContext context = SomeDataContext.GetNewDataContext(); 
     var table = context.GetTable(_EntityType); 
     var codeProp = (from member in context.Mapping.GetMetaType(_EntityType).DataMembers 
         where member.Name == _PropertyName 
         select member.Member).Single(); 
     ParameterExpression param = Expression.Parameter(_EntityType, "x"); 
     MemberExpression memberExp = Expression.Property(param, (PropertyInfo)codeProp); 
     Expression body = Expression.Equal(memberExp, Expression.Constant(value, typeof(char))); 
     Type lambdaType = typeof(Func<,>).MakeGenericType(_EntityType, typeof(bool)); 
     var predicate = Expression.Lambda(lambdaType, body, param); 
     object code = table.FirstOrDefault(predicate); 
     if (code != null) 
     { 
      return false; 
     } 
     return true; 
    } 

이 줄은 나쁜 :

나는이 점에 코드를 해킹했다 .... 속성은 일반적인 subcalsses을 허용하지 않기 때문에 - 그러나, 그것은 일반적인 PARMS을 필요로 내가 사용할 수 없습니다 :

 object code = table.FirstOrDefault(predicate); 

나는 도움이되지 않을 수 here 답변을 언급한다.

  • var enumerator = ((IEnumerable)table).GetEnumerator();object code = enumerator.MoveNext() ? enumerator.Value : null;
    는 식 트리를 구축하는 나의 시도에서 유용하지 않습니다. 내가하려고 할 때
  • IEnumerable<object> tableGeneric = ((IEnumerable)table).OfType<object>();
    는 문제가 있습니다 :
    object code = tableGeneric.FirstOrDefault(predicate);

그래서, 나는 꽤 붙어입니다. 거기에 어떤 아이디어가 있니?

감사합니다.

답변

0

당신이 찾고 될 수 있습니다 최종 실행이 내가 말할 수있는 지금까지 당신이 정말로 같은 방법 원하는 것입니다 : 당신이 필요로하는 당신은 체크 (들)을 수행 할 수 있도록

public bool IsValid<TEntity>() 
{ 
    // validation logic goes here 
} 

을하지만, 당신은 단지 그것을 사용할 수있는 런타임 타입이있는 방법을 구현해야합니다 이런 경우

public bool IsValid(Type entityType) 
{ 
    // ??? 
} 

는, 당신은 당신이 필요로하는 로직 첫 번째 코드 블록을 구현을하고 두 번째 방법을 다음과 같이 구현하십시오.

public bool IsValidWrapper(Type entityType) 
{ 
    // You may want to be stricter than this, but the essence is to 
    // get a handle to the generic method first... 
    MethodInfo genMethod = GetType().GetMethod("IsValid"); 

    // Bind it to the type you want to operate on... 
    MethodInfo method = genMethod.MakeGenericMethod(entityType); 

    // And invoke it... 
    return (bool) method.Invoke(this, null); 
} 

아름다움 콘테스트 나 성능 크라운에서 우승하지는 않지만 필요한 것을 얻을 수 있습니다. 그리고 성능에 문제가있는 경우 의 조회를 서명 bool delegate()이 포함 된 대리인에게 계속 보내면 지정된 유형에 대해 느린 리플렉션을 두 번 이상 사용하지 않고도 유형 바인딩을 수행 할 수 있습니다.

관련 문제