我拥有ChildAttributte的财产
public class AircraftFlight : BaseEntity
{
[Child(FilterType.Equal, "ParentTypeId", 13)]
public ICollection<ItemFileLink> Files { get; set; }
}
我创建表达式
Expression<Func<AircraftFlight, IEnumerable<ItemFileLink>>> q =
i => i.Files.Where(f => f.ParentTypeId == 13);
我的任务使用带有此参数的方法使用反射创建此表达式。转到T类型和查找属性(文件)。然后在属性文件调用方法Where
上使用condition(ParentTypeId == inputText)
private Expression<Func<T, IEnumerable<TChild>>> ExpressionConstructor<T, TChild>(
string prop (property Files),
string propertyName (property ParentTypeId),
object inputText,
FilterType condition)
你能帮助别人吗?
答案 0 :(得分:0)
以下是如何通过Expression API完全实现的。我已经添加了我的类假设的假设。如果存在偏差,则需要更改设置的表达式。
在进入代码之前,这似乎是相当静态的代码,似乎不需要反射。我想你有正确的理由走这条路。完全相同的事情也可以通过反射命名空间下的类来实现。
class AircraftFlight
{
internal ICollection<ItemFileLink> Files { get; set; }
}
class ItemFileLink
{
internal int ParentTypeId { get; set; }
}
static void Main(string[] args)
{
Type aircraftFlightType = typeof(AircraftFlight);
Type itemFileLinkType = typeof(ItemFileLink);
// Create object of desired type
ParameterExpression aircraftFlightObject = Expression.Parameter(aircraftFlightType, "parameter");
// Locate files property
MemberExpression filesPropertyExpression = Expression.Property(aircraftFlightObject, "Files");
// Getting where method call for Files property
var whereMethod = new Func<IEnumerable<ItemFileLink>, Func<ItemFileLink, bool>, IEnumerable<ItemFileLink>>(Enumerable.Where);
// Getting item types and parentId property
ParameterExpression itemFileLinkExpression = Expression.Parameter(itemFileLinkType);
Expression parentTypeIdExpression = Expression.Property(itemFileLinkExpression, "ParentTypeId");
// Create the lambda for where method (your condition for where clause)
var lambdaForWhere = Expression.Lambda(Expression.Equal(parentTypeIdExpression, Expression.Constant(13)), itemFileLinkExpression);
// Create where method call
var whereMethodGeneric = whereMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(itemFileLinkType);
MethodCallExpression whereCall = Expression.Call(null, whereMethodGeneric, filesPropertyExpression, lambdaForWhere);
// Create parent object
AircraftFlight aircraftFlight = new AircraftFlight();
aircraftFlight.Files = new Collection<ItemFileLink>();
aircraftFlight.Files.Add(new ItemFileLink { ParentTypeId = 1 });
aircraftFlight.Files.Add(new ItemFileLink { ParentTypeId = 13 });
aircraftFlight.Files.Add(new ItemFileLink { ParentTypeId = 1 });
aircraftFlight.Files.Add(new ItemFileLink { ParentTypeId = 13 });
aircraftFlight.Files.Add(new ItemFileLink { ParentTypeId = 1 });
aircraftFlight.Files.Add(new ItemFileLink { ParentTypeId = 1 });
// Invoke
var result = Expression.Lambda(whereCall, aircraftFlightObject).Compile().DynamicInvoke(aircraftFlight);
}
更新: 如果您不知道Files属性的类型,则可以先在方法中创建原型,然后创建特定的泛型方法。以下代码可能有所帮助:
// Prepare prototype where method
var whereMethod = new Func<IEnumerable<object>, Func<object, bool>, IEnumerable<object>>(Enumerable.Where);
// Prepare specific where method. itemFileLinkType can be replaced by any other type
var whereMethodGeneric = whereMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(itemFileLinkType);