2015-11-19 70 views
0

我有以下IQueryable構建一個IQueryable動態

 IQueryable<Class1> queryable = 
      (from c1 in DbContext.Set<Class1>() 
      from c2 in DbContext.Set<Class2>() 
      from c3 in DbContext.Set<Class3>() 
      where c1.Id == c2.Class1Id 
      && c2.Id == c3.Class2Id 
      && c3.ValueAsString == val 
      select c1); 

在上述情況下,val爲一個字符串。然而,Class3有幾個其他成員:

public string ValueAsString { get;private set; } 
    public int? ValueAsInteger { get; set; } 
    public DateTime? ValueAsDate { get; set; } 
    public decimal? ValueAsDecimal { get; set; } 
    public bool? ValueAsBoolean { get; set; } 

我需要修改IQueryable取決於「VAL」,這可以是上述5種類型中的一個類型。是否有可能構建IQueryable爲:

 IQueryable<Class1> queryable = 
      (from c1 in DbContext.Set<Class1>() 
      from c2 in DbContext.Set<Class2>() 
      from c3 in DbContext.Set<Class3>() 
      where c1.Id == c2.Class1Id 
      && c2.Id == c3.Class2Id     
      select c1); 

然後根據「VAL」的類型添加的決賽,之前執行?例如,如果val是一個小數,追加

c3.ValueAsDecimal == val 
+1

是的,這是可能的,但它應該在選擇之前。你嘗試過什麼嗎? –

+0

我沒跟着。 – user2524113

+0

希望提供一個問題來提供一些代碼,以顯示他試過的東西 –

回答

0

看起來像你的任務會更得心應手,而不是使用類似於SQL的LINQ的表達。我可以看到你的類相互有主鍵連接,如果使用性能,這種查詢可以看大約是這樣的:

Expression<Func<Class3, bool>> filterExpression = GetFilterExpression(val); //returns expression bases on val type 

var queryable = DbContext.Set<Class1>() 
          .Include(cl1=>cl1.Class2.Class3) //or .Include(cl1=>cl1.Class2.Select(cl2=>cl2.Class3)) depending on your object relationships 
          .Where(filterExpression); 

包括這裏被使用,如果你需要加載你的根的Class2和Class3的情況下, Class1類型的實體。如果你不需要它們,你可以跳過.Include()結構。 GetFilterExpression的

例子:

public Expression<Func<Class1, bool>> GetFilterExpression(string value) 
{ 
    return cl1 => cl1.Class2.Class3.ValueAsString == value; 
} 
+0

不會GetFilterExpression需要返回Expression >以便用作IQueryable中的'where'? – user2524113

+0

是的,你是對的,我犯了一個錯字。 –

0

這實際上是很容易的,你可以叫.Where(...)條件時通過。您只需預先選擇所有值c1,c2c3,然後在添加.Where(...)調用後,可以從結果中選擇c1值。像這樣:

var q = (
    from c1 in dbContext.Set<Class1>() 
    from c2 in dbContext.Set<Class2>() 
    from c3 in dbContext.Set<Class3>() 
    where c1.Id == c2.Class1Id 
    && c2.Id == c3.Class2Id 
    select new { c1, c2, c3 } 
); 
object var = ...; // Some value 
if (var is decimal) 
{ 
    q = q.Where(x => x.c3.ValueAsDecimal == (decimal)var); 
} 
else if (var is DateTime) 
{ 
    q = q.Where(x => x.c3.ValueAsDate == (DateTime)var); 
} 
// TODO: Add other types of 'var' 

var queryable = q.Select(x => x.c1);