2009-08-24 86 views
1

我正在處理ASP.NET MVC中的一個應用程序,該應用程序有許多查找表,所有的表格Linq-to-Sql的代碼重用 - 創建'通用'查找表

LookUp { 
    Id 
    Text 
} 

正如您所看到的,這只是將Id映射到文本值。這些用於諸如顏色之類的東西。我現在有很多這樣的東西,現在有6種,可能很快就會更多。

我想放在一起,可以通過AJAX使用的API,允許用戶從這些查找表添加/列表/刪除值,因此,例如我可能有這樣的事情:

http://example.com/Attributes/Colours/[List/Add/Delete]

我目前的問題是,很明顯,不管我使用的是哪個查找表,的一切其他情況都完全一樣。所以真的不應該重複任何代碼。

我目前有一個自定義路由,它指向一個'AttributeController',它根據URL(即http://example.com/Attributes/Colours/List想要'顏色'表)計算出有問題的屬性/查找表。我將屬性(Colors - 一個字符串)和操作(List/Add/Delete)以及任何其他所需的參數(如果我想將紅色添加到列表中的話稱爲「Red」)傳遞迴我的存儲庫,其中實際工作被執行。

事情在這裏開始變得混亂,因爲目前我已經採取了對屬性字符串的開關/情況,然後可以獲取對應於特定查找表的Linq-to-Sql實體。我覺得這很骯髒,因爲我發現自己不得不在每個查找實體上寫相同的操作,唉!

我真正想做的是有一些映射,我可以簡單地傳入屬性名稱並獲取某種形式的通用查找對象,從而無需關心就可以執行所需的操作關於類型。

有沒有辦法做到這一點到我的Linq-To-Sql實體?我試圖讓他們實現一個基本的接口(IAttribute),它只是規定了ID/Text屬性,但是做這樣的事情會失敗:

System.Data.Linq.Table<IAttribute> table = GetAttribute("Colours"); 

正如我不能轉換System.Data.Linq.Table<Colour>System.Data.Linq.Table<IAttribute>

有沒有辦法讓這些查找表爲'通用'?

道歉,這是一個大腦轉儲的位。這裏確實存在信息丟失的情況,所以如果您想了解更多詳情,請告訴我。乾杯!

回答

1

您有2個選項。

  1. 使用Expression Trees動態創建lambda表達式
  2. 使用Dynamic LINQ在斯科特谷的博客

我已經看了兩個選項,並已成功實現表達式樹爲我的首選方法,因爲詳細。

下面是我創建了一個例子功能:使用switch語句(未測試)

private static bool ValueExists<T>(String Value) where T : class 
    { 
     ParameterExpression pe = Expression.Parameter(typeof(T), "p"); 
     Expression value = Expression.Equal(Expression.Property(pe, "ColumnName"), Expression.Constant(Value)); 
     Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(value, pe); 
     return MyDataContext.GetTable<T>().Where(predicate).Count() > 0; 
    } 
+0

太好了,就是我所需要的。表達樹看起來完美的工作:) – CapBBeard 2009-08-24 20:49:18

1

相反的,你可以使用一個查找字典。這是psuedocode-ish,但這是解決問題的方法之一。您必須手動維護字典,但它應該比開關更容易。

它看起來像DataContext.GetTable()方法可能是你的問題的答案。如果你知道你想要操作的linq實體的類型,你可以得到一張表。

Dictionary<string, Type> lookupDict = new Dictionary<string, Type> 
{ 
    "Colour", typeof(MatchingLinqEntity) 
    ... 
} 

Type entityType = lookupDict[AttributeFromRouteValue]; 
YourDataContext db = new YourDataContext(); 
var entityTable = db.GetTable(entityType); 
var entity = entityTable.Single(x => x.Id == IdFromRouteValue); 
// or whatever operations you need 
db.SubmitChanges() 

Suteki Shop project中有一些非常光滑工作。您可以查看他們對IRepository<T>和IRepositoryResolver的實現以獲取通用存儲庫模式。這對IoC容器非常有效,但如果性能可以接受,則可以使用反射手動創建它們。如果您有或可以將IoC容器添加到項目中,我會使用此路線。如果你走這條路線,你需要確保你的IoC容器支持開放泛型,但是我很確定所有主要玩家都這麼做。