简体   繁体   中英

Linq SubSelect with Expression Trees

I have a Linq Statement with a SubSelect:

query1 = from d in drivers 
         where d.Klasse == 3 && cars.Where(c => c.Driver == d.Name && c.Power == 120).Count() > 0 
         select d;

This works fine. Now I want to do the same with expression trees.

This is, what I've got so far.

ParameterExpression peCar = Expression.Parameter(typeof(Car), "c");
ParameterExpression peDriver = Expression.Parameter(typeof(Driver), "d");
Expression eKlasse = Expression.Property(peDriver, "Klasse");
Expression ePower = Expression.Property(peCar, "Power");
Expression eDriver = Expression.Property(peCar, "Driver");
Expression eName = Expression.Property(peDriver, "Name");

Expression eEx1 = Expression.Equal(eKlasse, Expression.Constant(3, typeof(int)));
Expression eEx2 = Expression.Equal(eDriver, eName);
Expression eEx3 = Expression.Equal(ePower, Expression.Constant(120, typeof(int)));
Expression eEx4 = Expression.And(eEx2, eEx3);

Expression<Func<Car, bool>> whereConditionSub = Expression.Lambda<Func<Car, bool>>(eEx4, new ParameterExpression[] { peCar });

Expression eSub1 = (Expression)cars.AsQueryable<Car>().Where(whereConditionSub).Count();
Expression eSub2 = Expression.GreaterThan(eSub1, Expression.Constant(0, typeof(int)));
Expression eEx5 = Expression.And(eEx1, eSub2);

Expression<Func<Driver, bool>> whereCondition = Expression.Lambda<Func<Driver, bool>>(eEx5, new ParameterExpression[] { peDriver });

query1 = drivers.AsQueryable<Driver>().Where(whereCondition);

But I'm stuck on how to get the Sub-Query as an Expression into the main query.

Expression eSub1 = (Expression)cars.AsQueryable<Car>().Where(whereConditionSub).Count();

Any idea how to do this? Is this possible at all?

Wow, that seems like a lot of not readable code. Im unsure why you would like to have something like this, but anyways... You cannot cast an int to an Expression, it wont work. Count delivers you the result, so it executes the expression. You need to catch the expression before, and add the count as a method call on top. Something like:

var whereExp = cars.AsQueryable<Car>().Where(whereConditionSub).Expression;
var countMethod = new Func<IQueryable<Car>, int>(Queryable.Count).Method;
var eSub1 = Expression.Call(countMethod, whereExp);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM