Tôi đang cố gắng xây dựng một biểu thức lambda sẽ được kết hợp với các biểu thức khác thành một cây biểu thức khá lớn để lọc. Điều này làm việc tốt cho đến khi tôi cần phải lọc bởi một thuộc tính bộ sưu tập phụ.Xây dựng một cây biểu thức động để lọc trên thuộc tính bộ sưu tập
Làm thế nào để bạn xây dựng một biểu thức Lambda sẽ lọc bằng cách sử dụng Bất kỳ() trên thuộc tính của một bộ sưu tập là thuộc tính của đối tượng gốc?
Ví dụ:
CurrentDataSource.Offices.Where(o => o.base_Trades.Any(t => t.Name == "test"))
Đây là cách tôi sẽ xây dựng biểu thức tĩnh nhưng tôi cần phải xây dựng nó tự động. Xin lỗi vì sự nhầm lẫn.
Edit: Đây là một đoạn làm thế nào tôi xử lý các biểu thức ít phức tạp hơn:
IQueryable<Office> officeQuery = CurrentDataSource.Offices.AsQueryable<Office>();
ParameterExpression pe = Expression.Parameter(typeof(Office), "Office");
ParameterExpression tpe = Expression.Parameter(typeof(Trades), "Trades");
Expression SimpleWhere = null;
Expression ComplexWhere = null;
foreach (ServerSideFilterObject fo in ssfo)
{
SimpleWhere = null;
foreach (String value in fo.FilterValues)
{
if (!CollectionProperties.Contains(fo.PropertyName))
{
//Handle singleton lambda logic here.
Expression left = Expression.Property(pe, typeof(Office).GetProperty(fo.PropertyName));
Expression right = Expression.Constant(value);
if (SimpleWhere == null)
{
SimpleWhere = Expression.Equal(left, right);
}
else
{
Expression e1 = Expression.Equal(left, right);
SimpleWhere = Expression.Or(SimpleWhere, e1);
}
}
else
{
//handle inner Collection lambda logic here.
Expression left = Expression.Property(tpe, typeof(Trades).GetProperty("Name"));
Expression right = Expression.Constant(value);
Expression InnerLambda = Expression.Equal(left, right);
//Problem area.
Expression OfficeAndProperty = Expression.Property(pe, typeof(Office).GetProperty(fo.PropertyName));
Expression OuterLambda = Expression.Call(OfficeAndProperty, typeof(Trades).GetMethod("Any", new Type[] { typeof(Expression) }),InnerLambda);
if (SimpleWhere == null)
SimpleWhere = OuterLambda;
else
SimpleWhere = Expression.Or(SimpleWhere, OuterLambda);
}
}
if (ComplexWhere == null)
ComplexWhere = SimpleWhere;
else
ComplexWhere = Expression.And(ComplexWhere, SimpleWhere);
}
MethodCallExpression whereCallExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { officeQuery.ElementType }, officeQuery.Expression, Expression.Lambda<Func<Office, bool>>(ComplexWhere, new ParameterExpression[] { pe }));
results = officeQuery.Provider.CreateQuery<Office>(whereCallExpression);
Bạn đang hỏi cách xây dựng một cây biểu thức? – SLaks
Tôi không chắc chắn cách cấu trúc phân cấp hoạt động trong ví dụ của bạn. Bạn có thể xây dựng thêm một chút về điều đó không? Văn phòng có phải là gốc và sau đó mỗi Văn phòng có một bộ sưu tập Giao dịch không? Và bạn muốn lọc tên thương mại? Bộ lọc là nơi tôi bị mất một chút. Lấy làm tiếc. –
Không, tôi không chắc chắn về cú pháp được sử dụng để xây dựng một biểu thức với một cuộc gọi phương thức nội bộ và một biểu thức cho một tham số. Trong trường hợp này, tôi nhận được một lỗi nói rằng Any() không thể được tìm thấy bởi vì các tham số của tôi không khớp với định nghĩa. Trong trường hợp này, tôi không chắc chắn nếu đó là vì tôi tắt cú pháp hoặc nếu Any() không được hỗ trợ theo cách tôi đang sử dụng nó. – George