How about placing the condition as a part of Join
method source?
With that approach your condition requires Expression<Func<B, true>>
and you can easily make one using Expression Tree.
List<T> result;
var param = Expression.Parameter(typeof(B), "x");
var trueExp = Expression.Constant(true);
var condition = Expression.Equal(Expression.Property(param, prop), trueExp);
var whereLambda = Expression.Lambda<Func<B, bool>>(condition, param);
using (var db = new DataContext())
{
result = db.Table1
.Join(db.Table2.Where(whereLambda),
t1 => t1.Id,
t2 => t2.Id,
(t1, t2) => new { t1, t2 })
.Select(t => t.t1)
.ToList();
}
return result;
Update
If you want to follow your initial design you should make the compiler infer your anonymous type:
public static Expression<Func<T, bool>> GetPropertyCondition<T>(T source, string prop)
{
var param = Expression.Parameter(typeof(T), "x");
var trueExp = Expression.Constant(true);
var condition = Expression.Equal(
Expression.Property(
Expression.Property(param, "t2"), prop),
trueExp);
var whereLambda = Expression.Lambda<Func<T, bool>>(condition, param);
return whereLambda;
}
and you can call it like that:
var result = new List<A>();
var anonymous = new { t1 = (A)null, t2 = (B)null };
var condition = GetPropertyCondition(anonymous, prop);
using (var db = new DataContext())
{
result = db.Table1.AsQueryable()
.Join(db.Table2.AsQueryable(), t1 => t1.Id, t2 => t2.Id, (t1, t2) => new { t1, t2 })
.Where(condition)
.Select(t => t.t1)
.ToList();
}
return result;
it uses the fact, that every anonymous type object with the same set of properties (both property name and property type have to match) within the assembly share the same underlying anonymous class. So typeof(anonymous)
here matches type returned by Join
extension method.