PredicateBuilder可以生成跨越多个表的谓词吗? [英] Can PredicateBuilder generate predicates that span multiple tables?

查看:223
本文介绍了PredicateBuilder可以生成跨越多个表的谓词吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想动态生成跨越Linq语句中的Join跨越多个表的谓词.在以下代码片段中,我想使用PredicateBuilder或类似的结构来替换以下代码中的"where"语句:

I would like to dynamically generate predicates that span multiple tables across a Join in a Linq statement. In the following code snippet, I want to use PredicateBuilder or a similar construct to replace the 'where' statement in the following code:

替换:

public class Foo
{
    public int FooId;  // PK
    public string Name;
}

public class Bar
{
    public int BarId;  // PK
    public string Description;
    public int FooId;  // FK to Foo.PK
}

void Test()
{
    IQueryable<Foo> fooQuery = null;    // Stubbed out
    IQueryable<Bar> barQuery = null;    // Stubbed out

    IQueryable<Foo> query =
        from foo in fooQuery
        join bar in barQuery on foo.FooId equals bar.FooId
        where ((bar.Description == "barstring") || (foo.Name == "fooname"))
        select foo;
}

类似:

void Test(bool searchName, bool searchDescription)
{
    IQueryable<Foo> fooQuery = null;    // Stubbed out
    IQueryable<Bar> barQuery = null;    // Stubbed out

    IQueryable<Foo> query =
        from foo in fooQuery
        join bar in barQuery on foo.FooId equals bar.FooId
        select foo;

    // OR THIS

    var query =
        from foo in fooQuery
        join bar in barQuery on foo.FooId equals bar.FooId
        select new {foo, bar};

    var predicate = PredicateBuilder.False<Foo>();
    if (searchName)
    {
        predicate = predicate.Or(foo => foo.Name == "fooname");
    }
    if (searchDescription)
    {
        // Cannot compile
        predicate = predicate.Or(bar => bar.Description == "barstring");
    }
    // Cannot compile
    query = query.Where(predicate);
}

解决这个问题的任何想法,想法和策略吗?

Any thoughts, ideas, strategies for tackling this problem?

谢谢

EulerOperator

EulerOperator

推荐答案

我认为您的问题出在PredicateBuilder的T型上-一半的谓词作用在Foo上,另一半则作用在Bar上.

I think your problem is with the type T of your PredicateBuilder - half of your predicate if acting on a Foo, the other half is on a Bar.

您可以将其替换为简单的手动构建的查询:

You could replace this with a simple manually constructed query:

void Test()
{
    IQueryable<Foo> fooQuery = null;    // Stubbed out
    IQueryable<Bar> barQuery = null;    // Stubbed out

    IQueryable<Foo> query =
        from foo in fooQuery
        join bar in barQuery on foo.FooId equals bar.FooId
        select new {Foo = foo, Bar = bar};

    if (searchName) 
    {
        query = query.Where(fb => fb.Foo.Name == "fooname");
    }
    if (searchDescription)
    {
        query = query.Where(fb => fb.Bar.Description == "barstring");
    }

    // use query here
}

另一种方法是使用PredicateBuilder,但要使其在Foo,Bar对上起作用-例如.

An alternative method is to use PredicateBuilder but to make it work on the Foo,Bar couple - e.g.

class FooBar
{
   public Foo Foo {get;set;}
   public Bar Bar {get;set;}
}

void Test(bool searchName, bool searchDescription)
{
    IQueryable<Foo> fooQuery = null;    // Stubbed out
    IQueryable<Bar> barQuery = null;    // Stubbed out

    var query =
        from foo in fooQuery
        join bar in barQuery on foo.FooId equals bar.FooId
        select new FooBar
        {
           Foo = foo, 
           Bar = bar
        };

    var predicate = PredicateBuilder.False<FooBar>();
    if (searchName)
    {
        predicate = predicate.Or(foobar => foobar.Foo.Name == "fooname");
    }
    if (searchDescription)
    {
        predicate = predicate.Or(foobar => foobar.Bar.Description == "barstring");
    }
    query = query.Where(predicate);

    // use query here
}

这篇关于PredicateBuilder可以生成跨越多个表的谓词吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆