2011-11-20 127 views
1

我想創建一個查詢,「調整」它是基於元組的where子句。元組中的第一項包含一個枚舉值,指示要過濾的字段。第二個元組項是過濾器值。LINQ to SQL查詢在哪裏子句

注意下面的查詢不起作用:

 var query = from p in db.Categories 
     where (QueryBy.Item1 == CategoryFields.Name  && p.Name  == (string)(QueryBy.Item2)) || 
       (QueryBy.Item1 == CategoryFields.Id   && p.Id   == (long)(QueryBy.Item2) ) || 
       (QueryBy.Item1 == CategoryFields.Description && p.Description == (string)(QueryBy.Item2)) || 
       (QueryBy.Item1 == CategoryFields.SortOrder && p.SortOrder == (int)(QueryBy.Item2) ) 
     select... 

     if (query.Count() == 1) // ERRORS HERE CONVERSION OF INT 

類似的查詢僅與該where子句變化將作品:

 var query = from p in db.Categories 
     where (QueryBy.Item1 == CategoryFields.Name  && p.Name  == (string)(QueryBy.Item2)) 
     select... 

     if (query.Count() == 1) // Works HERE 

任何想法可能是錯誤的?是否可以用LINQ where子句進行短路評估,因此item2的投射失敗?有沒有更好的方法來實現調整where子句的總體目標?

在此先感謝您的幫助!

回答

3

LINQ to SQL不夠智能,無法優化您的查詢並根據您的QueryBy.Item1的值動態生成它。它將簡單地生成一個SQL查詢,讓SQL服務器爲自己做出決定。

如果您知道該錯誤是有意義的,因爲無法將一個值同時投射到int,longstring

在你的情況下,你會更好地動態生成正確的where子句。你可以用PredicateBuilder

IQueryable<Category> query = db.Categories; 

var whereClause = PredicateBuilder.False<Category>(); 

switch (QueryBy.Item1) 
{ 
    case CategoryFields.Name: 
     long id = (string)QueryBy.Item2; 
     whereClause = whereClause.Or(p => p.Name == name); 
     break; 

    case CategoryFields.Id: 
     string name = (string)QueryBy.Item2; 
     whereClause = whereClause.Or(p => p.Id == id); 
     break; 

    case CategoryFields.Description: 
     string des = (string)QueryBy.Item2; 
     whereClause = 
      whereClause.Or(p => p.Description == des); 
     break; 

    case CategoryFields.Id: 
     string sort = (int)QueryBy.Item2; 
     whereClause = 
      whereClause.Or(p => p.SortOrder == sort); 
     break; 
} 

query = query.Where(whereClause); 
+0

謝謝史蒂文!這適用於一個變化。最後一行:「query = query.Where(whereClause);」似乎過濾查詢。所以我移動了關於查詢的switch語句,並將查詢改爲:「IQueryable query =(db.Categories ...)。Where(whereClause);」 –