我有一个包含两个表的数据库:
public class A {
public string Name { get; set; }
public int Id { get; set; }
}
public class B {
public int Id { get; set; }
public bool Prop1 { get; set; }
public bool Prop2 { get; set; }
public bool Prop3 { get; set; }
public bool Prop4 { get; set; }
}
public class DataContext : DbContext {
DbSet<A> Table1 { get; set: }
DbSet<B> Table2 { get; set; }
}
我想写函数,它将作为参数“Prop1”,“Prop2”,...,“PropX” 并从Table1返回适当的行。 像这样:
public List<A> GetByProp(string prop) {
var result = new List<A>();
using (var db = new DataContext()) {
result = db.Table1.Join(db.Table2, t1=>t1.Id, t2=>t2.Id, (t1,t2)=>new {t1,t2}).
Where(????????). //t=>t.t2.prop == true
Select(t=>t.t2);
}
return result;
}
这样做的正确方法是什么?
我曾尝试使用表达式树,但我被卡住了......
如何用两个点构建表达式? (t.t2.prop == true)
如何将匿名类型(Join()生成)传递给泛型
var p = Expression.Parameter(typeof(???), t2); //??? - anonymous class
var t = Expression.Constant(true, typeof(bool));
var e = Expression.Equal(p, t);
var l = Expression.Lambda<Func<???, bool>>(e, p);
答案 0 :(得分:2)
如何将条件作为Join
方法源的一部分放置?
使用这种方法,您的条件需要Expression<Func<B, true>>
,您可以使用表达式树轻松制作一个。
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;
的更新强> 的
如果您想要遵循初始设计,您应该让编译器推断出您的匿名类型:
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;
}
你可以这样称呼它:
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;
它使用的事实是,程序集中具有相同属性集(属性名称和属性类型必须匹配)的每个匿名类型对象共享相同的基础匿名类。因此typeof(anonymous)
匹配Join
扩展方法返回的类型。