2011-04-08 147 views
0

我有幾個表都具有相同的列domainID,它們基本上只是控制哪些數據顯示在哪個網站上,因爲它們共享數據庫。傳遞lambda表達式作爲參數

所以當我去控制一個表的數據綁定時,我需要創建一個大的開關來處理不同的LINQ查詢。我想創建一個實用方法,它將表類型作爲參數,然後根據傳入的表中的列返回where子句。

public static IEnumerable<T> ExecuteInContext<T>(
       IQueryable<T> src) 
     { 
      int domain = 1;//hard coded for example 

      return src.Where(x => x.DomainID == domain);//Won't work, has to be a way to do this.    
     } 

我被卡在返回碼上。你不能簡單地構造一個像我一樣的where子句,因爲它不知道我在說什麼表。

我試圖調用第一種方法是這樣的:

using (DataClasses1DataContext db = new DataClasses1DataContext()) 
     { 

      var q = Utility.ExecuteInContext(db.GetTable<item>()); 

      Repeater1.DataSource = q; 
      Repeater1.DataBind(); 
     } 

我希望這說明了什麼,我試圖做的。

編輯: BrokenGlass的答案解決了我的問題。我想補充一點,你需要打開你的.dbml.cs文件,並用你的界面擴展表/類。我還想指出,如果我的專欄可以爲空,那麼該項目不會生成,它說它與我的界面不同。

回答

3

你必須限制您的T轉換爲屬性爲DomainID的類 - 您可以將這些接口實現添加到擴展數據模型的部分類中。

public interface IFoo 
{ 
    int DomainId { get; set; } 
} 
.. 

public static IQueryable<T> ExecuteInContext<T>(IQueryable<T> src) where T: IFoo 
{ 
    int domain = 1;//hard coded for example 
    return src.Where(x => x.DomainID == domain); 
} 
+0

當我嘗試調用此方法並將參數設置爲我的'item'表時,它表示沒有從'item'到'utility.IFoo'的顯式引用轉換。 – 2011-04-08 19:51:00

+0

您的item表類實現了'IFoo'嗎?這對於此工作是必需的。你可能需要在分類中添加它,我使用Linq到實體 - 希望Linq到SQL也是一樣,如果不是,那麼忽略這個答案 – BrokenGlass 2011-04-08 19:56:06

+0

我不知道該怎麼做。我現在擁有的是我的問題中的第二個代碼塊。 – 2011-04-08 19:58:21

0

你應該能夠在您的泛型參數轉換爲預期的類型......

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src) 
{ 
    int domain = 1;//hard coded for example 

    return src.Where(x => ((T)x).DomainID == domain); 
} 

但你意識到你已經創建了一個假設其類型參數將始終暴露特定屬性的通用方法是什麼?如果你要做到這一點,你應該申請一個generic type constraint的是T總是來源於一種類型的這個屬性...

例如:

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src) where T : IMyDomainObject 
+0

將調用此方法將總是有這些查詢包含'domainID'列的表,如果這就是你的意思。 – 2011-04-08 19:54:30

+0

它不允許我將參數轉換爲預期的類型。 – 2011-04-08 20:04:07

0

我不知道如果我明白你的意思,但也許你想添加一個WHERE子句:

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src)  

    where T: MyType //MyType exposing your DomainId 
    {    
     int domain = 1;//hard coded for example    
     return src.Where(x => x.DomainID == domain);//Won't work, has to be a way to do this.      
    } 
2
Expression pe = Expression.Parameter(typeof(T)); 
Expression prope = Expression.Property(pe, "DomainID"); 
Expression ce = Expression.Equals(prope, 
    Expression.Constant((int)1); 

Expression<Func<T,bool>> exp = 
Expression.Lambda<Func<T,bool>>(
    ce, pe); 

return query.Where(exp); 
+0

這看起來很可怕但很有趣 - 所以這種方法可以工作,不管T是什麼類型,如果它有一個屬性'DomainID'? – BrokenGlass 2011-04-08 19:58:23

+0

是的,如果你使用反射器,這正是編譯器所做的。 – 2011-04-09 05:00:13

相關問題