2010-02-04 82 views
2

我試圖讓微小的helper方法用於簡化日常操作 但在樣本:C#泛型LINQ的搜索條件

public static int getEntityId<Type, Entity>(String name) where Entity: class 
{ 
    Type type = _db.GetTable<Entity>().SingleOrDefault(t => t.name == name); 
    return 0; 
} 

我遇到錯誤:

Error 1 'Entity' does not contain a definition for 'name' and no extension method 'name' accepting a first argument of type 'Entity' could be found (are you missing a using directive or an assembly reference?) c:\work\asutp_migration\asutp_migration\Program.cs 89 62 asutp_migration 

其實,這是預計的錯誤,但如何解決這個問題? 所有使用此方法的表/類都具有「名稱」字段/屬性。

UPD 1: 根據建議我這樣做:

public partial class unit : IHasName 
{ 
} 

interface IHasName 
{ 
    string name { get; } 
    int id { get; } 
} 

public static int getEntityId<Type, Entity>(String name) where Entity: class, IHasName 
{ 
    Type type = _db.GetTable<Entity>().SingleOrDefault(t => t.name == name); 
    return (type == null) ? type.id : 0; 
} 

與代碼:

int i = getEntityId<unit>("м"); 
Console.WriteLine(i); 

我得到異常:

Unhandled Exception: System.NotSupportedException: The mapping of interface member IHasName.name is not supported. 

UPD 2: http://connect.microsoft.com/VisualStudio/feedback/details/344903/linq-to-sql-mapping-interface-member-not-supported-exception 我不敢相信。這與我的問題有關嗎?

UPD 3: 是啊,看來這是VS的問題:http://social.msdn.microsoft.com/Forums/en/linqtosql/thread/bc2fbbce-eb63-4735-9b2d-26b4ab8fe589

UPD 4:

public static int getEntityId<Type>(String name) where Type: class, IHasName 
{ 
    Type type = _db.GetTable<Type>().SingleOrDefault(t => t.name.Equals(name)); 
    return (type != null) ? type.id : 0; 
} 

所以這是一個解決方案,謝謝大家:-)

+0

有什麼你試圖用這個代碼實現的目標是什麼? – 2010-02-04 04:04:36

+0

我試圖防止像這樣的方法重複http://pastie.org/808750 – zerkms 2010-02-04 04:06:44

回答

6

好了,你會需要制定一個通用約束來指定比class更具體的內容。例如,如果您說where Entity : IHasNameIHasName定義了屬性name,那麼您將全部設置。

+0

該類定義是用內建的.dbml生成的。使用其他接口定製它們是個好主意嗎? 我聽說反射也可以提供幫助,但我不能選擇哪種解決方案更好。 – zerkms 2010-02-04 04:10:55

+2

我認爲內置.dbml生成創建部分類。你可以進入部分定義的另一個文件,並修改類的定義爲'public partial class MyClass:IHasName' – 2010-02-04 04:16:56

+1

+1,用於微妙和適當的lolcats/lolcode引用(有意或無意)。 – Aaronaught 2010-02-04 04:21:31

0

我會想你正在尋找的東西,如:

public static int getEntityID<T>(string name) where T : Entity { 
    T obj = _db.GetTable<T>().SingleOrDefault(t => t.name == name); 
    return obj != null ? obj.id : 0; 
} 

這裏,實體將是一些基礎類(或接口)

public abstract class Entity { 
    public int id { get; set;} 
    public string name { get; set; } 
} 

和你的類型會從中導出。

+0

nope,我的代碼中的實體是用於linq to sql的表名。 像_db.element_type ... 「element_type」部分是實體。它可以在3個或更多表名的集合內進行更改。 – zerkms 2010-02-04 04:12:35

+0

@Jimmy,我認爲zerkms打算使用'Entity'作爲泛型分類器(而不是'T,K',他使用'Type,Entity') – 2010-02-04 04:12:47

+0

@Jim,yep。我對c#非常陌生,所以我不知道還有一些常見的meta名稱:-( – zerkms 2010-02-04 04:14:46

1

都會響起吉米的職位和油槍加油的回答是:

public static int GetEntityID<T>(string name) 
    where T : IAnimal 
{ 
    T obj = _db.GetTable<T>().SingleOrDefault(t => t.name == name); 
    return obj != null ? obj.id : 0; 
} 

EDIT2:既然你是新來此,這裏是上面的代碼使用的例子:

/* You have a LinqToSql object of type Manatee */ 
int manateeId = MyClass.GetEntity<Manatee>("Jack"); 

這聽起來像你」只是試圖實現一個存儲庫模式,這使事情變得更容易。下面是如何做到這一點在LinqToSql一個例子:http://aspalliance.com/1672_Implementing_the_Repository_Pattern_with_LINQtoSQL.3

一旦你學會了如何做到這一點,你可以修改它使用了NHibernate的或ADO.NET

編輯:

public interface IAnimal 
{ 
    string name; 
} 

public Manatee : IAnimal 
{ 
    public string name {get;set;} 
    public int Age {get;set;} 
    public strin Weight {get;set} 
} 
+0

這會得到相同的錯誤,因爲靜態地解決K是否具有名稱屬性或不存在 – zerkms 2010-02-04 04:30:52

+0

@zerkms,我做了幾個編輯以使其更容易,並向您展示如何設置Interface和繼承接口的類。注意Manatee類和繼承該接口的任何其他類都需要'name'屬性。只是說「這個類肯定會實現這些屬性和方法」這就是爲什麼你想要實現的泛型方法可以使用Linq查詢'T obj = _db.GetTable ().SingleOrDefault(t => t.name = = name);'並且不用擔心炸燬。 – 2010-02-04 04:39:42

+0

如何定義接口的屬性?我得到有關接口的錯誤不能包含字段:-S – zerkms 2010-02-04 04:42:11