我試圖創建一個通用的數據檢索過程。我目前的工作,但有一部分似乎不正確,我希望有一個更好的方法來實現它。T實現接口的通用方法<T>
這樣的想法是,我有類數據庫中的每個表,這裏是一個類的實例:
public class CMCGRGRGROUP : IFacetsObject<CMCGRGRGROUP>
{
public int GRGR_CK { get; set; }
public string GRGR_NAME { get; set; }
public string GRGR_ADDR1 { get; set; }
public IEnumerable<CMCGRGRGROUP> ToObject(DataTable table)
{
return table.AsEnumerable().Select(row =>
{
return new CMCGRGRGROUP
{
GRGR_CK = Convert.ToInt32(row["GRGR_CK"]),
GRGR_NAME = row["GRGR_NAME"].ToString(),
GRGR_ADDR1 = row["GRGR_ADDR1"].ToString()
};
});
}
}
你會發現,這個類實現自己的類型的接口。該接口只定義了一個名爲ToObject
方法,它用於將數據錶轉換爲一類特殊類型的:
public interface IFacetsObject<T>
{
IEnumerable<T> ToObject(DataTable obj);
}
現在,這裏是我用來執行查詢的方法:
public IEnumerable<T> ExecuteQuery<T>(string sql, IFacetsObject<T> obj) where T : new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return obj.ToObject(dt); //this is the interface method
}
}
所以主要問題是: 如何才能知道T應該實現IFacetsObject<T>
?這樣我就不必通過IFacetsObject<T>
作爲參數。理想情況下,我可以改變返回行是這樣的:
return T.ToObject(dt);
,並調用它是這樣的:
var result = ExecuteQuery<CMCGRGRGROUP>(sql).Take(5);
,而不是像這樣:
var result = ExecuteQuery<CMCGRGRGROUP>(sql, new CMCGRGRGROUP()).Take(5);
我承認我對泛型還不是非常熟悉,所以在實現中可能有些東西是不正確的。
我看到你使用orkish變量命名約定 – Jonesopolis
是的,它們很糟糕 - 不幸的是沒有命名數據庫表只是爲了保持名稱一致。 – Goose
您無法從旁邊的界面繼承。(接口是_implemented_,行爲/實現是_inherited_) – sehe