2011-03-14 102 views
5

我想動態生成跨Linix語句中的Join的多個表的謂詞。在下面的代碼片段,我想用PredicateBuilder或類似的結構來代替「其中」語句下面的代碼:PredicateBuilder可以生成跨越多個表的謂詞嗎?

替換:

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); 
} 

解決這個問題的想法,想法和策略?

感謝,

EulerOperator

回答

6

我覺得你的問題是你PredicateBuilder的T型 - 你的謂詞的一半,如果作用於富,另一半則是在一間酒吧。

你可以用一個簡單的手動構造查詢替換此:

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而是使之在美孚,酒吧夫婦工作 - 例如

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 
}