Linq to sql 使用LINQ和动态创建的谓词进行动态搜索

Linq to sql 使用LINQ和动态创建的谓词进行动态搜索,linq-to-sql,Linq To Sql,我动态构建了一些谓词,这些谓词将以下签名作为参数传递到函数中: Expression<Func<TblTableR, bool>> TableRPredicate, Expression<Func<TblTableN, bool>> suspectNamesPredicate, Expression<Func<TblTableS, bool>> TableSPredicate, Expression<Func<T

我动态构建了一些谓词,这些谓词将以下签名作为参数传递到函数中:

Expression<Func<TblTableR, bool>> TableRPredicate,
Expression<Func<TblTableN, bool>> suspectNamesPredicate,
Expression<Func<TblTableS, bool>> TableSPredicate,
Expression<Func<TblTableI, bool>> suspectTableIPredicate,
其结果是将生成的任何“where”子句放入JOIN语句中,例如:

left outer join tblTableI on tblTableITableRID = tblTableRID 
   AND (expression created by predicate)
实际上,创建的最终SQL是不正确的。它正在创建以下类型的sql

 select * from table1 left outer join table2 on field1 = field2 
    AND field3 = 'CRITERIA'
问题在于末尾的AND子句——返回的行太多。本质上,我希望将where子句放入语句中,而不是让它将额外的条件粘贴到join中

大概是这样的:

select * from table1 left outer join table2 on field1 = field2 
    WHERE field3 = 'CRITERIA'
我已尝试在中添加Where子句,如下所示:

...
...
...
select r.TblTableRID).Where(TableRPredicate).Distinct();
但由于每个谓词上都有泛型参数,因此无法编译

如果将LINQ查询修改为仅从一个表中选择并使用谓词,则会正确生成WHERE子句

有什么想法吗?

(编辑后澄清)

步骤1;更改最终选择,将所有三个实体选择为匿名类型;对我来说(在Northwind上测试),即:

select new {emp, cust, order};
步骤2;使用我在下面添加的扩展方法将过滤器应用于此;对我来说,此筛选看起来像:

var qry2 = qry.Where(x => x.emp, employeeFilter)
            .Where(x => x.cust, custFilter)
            .Where(x => x.order, orderFilter);
步骤3;现在,从这个过滤的查询中选择您实际想要的实体:

var data = qry2.Select(x => x.order)
下面是扩展方法:

static IQueryable<T> Where<T,TValue>(
    this IQueryable<T> source,
    Expression<Func<T, TValue>> selector,
    Expression<Func<TValue, bool>> predicate)
{
    var row = Expression.Parameter(typeof (T), "row");
    var member = Expression.Invoke(selector, row);
    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Invoke(predicate, member), row);
    return source.Where(lambda);
}
静态IQueryable,其中(
这是可靠的消息来源,
表达式选择器,
表达式(谓词)
{
var row=表达式参数(typeof(T),“row”);
var member=Expression.Invoke(选择器,行);
var lambda=表达式.lambda(
表达式.Invoke(谓词,成员),行);
返回源。其中(λ);
}
(在澄清后编辑)

步骤1;更改最终选择,将所有三个实体选择为匿名类型;对我来说(在Northwind上测试),即:

select new {emp, cust, order};
步骤2;使用我在下面添加的扩展方法将过滤器应用于此;对我来说,此筛选看起来像:

var qry2 = qry.Where(x => x.emp, employeeFilter)
            .Where(x => x.cust, custFilter)
            .Where(x => x.order, orderFilter);
步骤3;现在,从这个过滤的查询中选择您实际想要的实体:

var data = qry2.Select(x => x.order)
下面是扩展方法:

static IQueryable<T> Where<T,TValue>(
    this IQueryable<T> source,
    Expression<Func<T, TValue>> selector,
    Expression<Func<TValue, bool>> predicate)
{
    var row = Expression.Parameter(typeof (T), "row");
    var member = Expression.Invoke(selector, row);
    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Invoke(predicate, member), row);
    return source.Where(lambda);
}
静态IQueryable,其中(
这是可靠的消息来源,
表达式选择器,
表达式(谓词)
{
var row=表达式参数(typeof(T),“row”);
var member=Expression.Invoke(选择器,行);
var lambda=表达式.lambda(
表达式.Invoke(谓词,成员),行);
返回源。其中(λ);
}

Marc,我已经更新了帖子,让事情变得更清楚了。彼得马克,我已经更新了帖子,让事情更清楚一点。彼得