Ref to:Creating a ValidationAttribute to ensure unique column values.
Ok… Let’s try reframing the question:
from here I have ripped this code:
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);
}
It’s a DataContext Extension Method that has stuff I need. However, it requires generic parms I don’t have available – attributes don’t allow generic subcalsses, so….
I have hacked the code to this point:
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;
}
This line is bad:
object code = table.FirstOrDefault(predicate);
as I stated here the answers to which don’t help.
var enumerator =
((IEnumerable)table).GetEnumerator();object
code = enumerator.MoveNext() ?
enumerator.Value : null;
is not useful in my attempt to build the expression tree.IEnumerable<object> tableGeneric =
((IEnumerable)table).OfType<object>();
has issues when I try:
object code = tableGeneric.FirstOrDefault(predicate);
So, I am pretty stuck. Any ideas out there?
Thanks.
The end-run you may be looking for is that as far as I can tell you really want a method like:
So that you can perform the check(s) that you need, but you need to implement it in a method that only has the run-time-type available to it:
If that is the case, then you implement the first code-block with the logic you need, and you implement the second method as:
It won’t win any beauty contests or performance crowns, but it will get you what you need. And note that if performance is a concern, you could keep a lookup from
Typeto a delegate with the signaturebool delegate()so that you do not have to use slow reflection for a given type more than once to perform the type binding.