ExpressMapper有一个Ignore
方法,如下所示:
public IMemberConfiguration<T, TN> Ignore<TMember>(Expression<Func<TN, TMember>> dest)
{
if (dest == null)
{
throw new ArgumentNullException("dst");
}
if (!(dest.Body is MemberExpression))
{
throw new Exception("MemberExpression should return one of the properties of destination class");
}
foreach (var typeMapper in _typeMappers)
{
typeMapper.Ignore(dest);
}
return this;
}
我想添加自己的IgnoreAll
方法,该方法迭代Type上的所有属性,并为每个属性调用Ignore
方法。这就是我到目前为止所做的:
public static IMemberConfiguration<TSource, TDestination> IgnoreAll<TSource, TDestination>(
this IMemberConfiguration<TSource, TDestination> config)
{
var props = typeof (TDestination).GetProperties();
foreach (var prop in props)
{
var propertyInfo = typeof(TDestination).GetProperty(prop.Name);
var entityParam = Expression.Parameter(typeof(TDestination), "e");
Expression columnExpr = Expression.Property(entityParam, prop);
if (propertyInfo.PropertyType != typeof(object))
columnExpr = Expression.Convert(columnExpr, typeof(object));
var expression = Expression.Lambda<Func<TDestination, object>>(columnExpr, entityParam);
config.Ignore(expression);
}
return config;
}
运行此代码时,出现错误:
MemberExpression应该返回目标的一个属性 类
从上面Ignore
方法的来源可以看出,我生成的表达式失败了以下条件:
if (!(dest.Body is MemberExpression))
{
throw new Exception("MemberExpression should return one of the properties of destination class");
}
所以我的问题是:
在扩展方法中需要更改哪些内容才能生成Expression
方法所期望的正确Ignore
?
编辑:顺便说一句,MemberConfiguration
课程的完整来源就在这里:https://github.com/fluentsprings/ExpressMapper/blob/master/ExpressMapper%20NET40/MemberConfiguration.cs
答案 0 :(得分:1)
好吧,我想出来了,我得告诉你,这是一个很糟糕的事。
public static IMemberConfiguration<TSource, TDestination> IgnoreAll<TSource, TDestination>(
this IMemberConfiguration<TSource, TDestination> config)
{
// First we'll get the collection of properties to iterate over.
var props = typeof (TDestination).GetProperties();
foreach (var prop in props)
{
// Get the property information.
var propertyInfo = typeof(TDestination).GetProperty(prop.Name);
// Create an expression that points to the property.
var entityParameter = new ParameterExpression[]
{
Expression.Parameter(typeof(TDestination), "e")
};
var propertyExpression = Expression.Property(entityParameter[0], prop);
// Create a Func<,> using the TDestination and the property's type
// for the Type parameters.
var funcType = typeof(Func<,>).MakeGenericType(typeof(TDestination), propertyInfo.PropertyType);
// We need to create an Expression using Expression.Lambda<>, but we
// don't know the types involved so we have to do this using reflection.
var lambdaMethod = typeof (Expression)
.GetMethods()
.Single(m => m.IsGenericMethod &&
m.GetParameters()[0].ParameterType == typeof(Expression) &&
m.GetParameters()[1].ParameterType == typeof(ParameterExpression[]));
var lambdaMethodConstructed = lambdaMethod.MakeGenericMethod(funcType);
var expression = lambdaMethodConstructed.Invoke(
null,
new object[] { propertyExpression, entityParameter });
// Now we need to construct the Ignore method using the property's Type.
var ignoreMethod = config.GetType().GetMethod("Ignore");
var constructed = ignoreMethod.MakeGenericMethod(propertyInfo.PropertyType);
// Finally, we call the constructed Ignore method, using
// our expression as the argument.
constructed.Invoke(config, new object[] { expression });
}
return config;
}