Я написал статический метод, который даст соответствующий предикат лямбда, используя выражение api для полей другого типа.
static Func<T, bool> Process<T>(string type)
{
ParameterExpression parameter = Expression.Parameter(typeof(T));
Expression predicate = Expression.Constant(true);
if (type == "Start")
{
Expression prop = Expression.Property(parameter, type);
Expression filter = Expression.LessThan(prop, Expression.Constant(DateTime.Now));
predicate = Expression.AndAlso(predicate, filter);
}
//TODO: more if statments to come
var lambda = Expression.Lambda<Func<T, bool>>(predicate, parameter);
return lambda.Compile();
}
Приведенный выше код работает нормально, если я выполняю одну операцию запроса в linq, например:
var del = Process<MyClass>("Start");
var data = DbContext.MyClass.Where(del); //gets the result data
public class MyClass
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public long Id { get; set; }
}
Теперь, если я сделаю соединение на объекте MyClass
var data = DbContext.MyClass
.Join(DbContext.Detail, mc => mc.Id, detail => detail.Id, (m, d) =>
new { m = m, d = d})
.Where(del);
Приведенные выше строки дают ошибку времени компиляции
Error CS1929 'IQueryable<<anonymous type: MyClass m, Detail d>>' does not contain a definition for 'Where' and the best extension method overload 'EnumerableRowCollectionExtensions.Where<MyClass>(EnumerableRowCollection<MyClass>, Func<MyClass, bool>)' requires a receiver of type 'EnumerableRowCollection<MyClass>'
Я понимаю, что .Where()
теперь ожидает анонимный тип, который имеет m и d , но не уверен, как решить эту проблему.
Я довольно новичок в Expression API. Не уверен, как достичь.
Я пытался добиться этого, создавая переменную анонимного типа, но это переменная, а не сам тип, чтобы передать ее Process<T>()
.