我有一个名为 DAL_Base 的基类,用于执行大部分SQL提升的大型项目。
DAL_Base 包含SELECT
语句,GetRecords()
方法和virtual FillData(IDataRecord)
字段。
public class DAL_Base<T> where T : IDisposable, new() {
private string connStr;
public DAL_Base() {
connStr = ConfigurationManager.ConnectionStrings["CompanyDatabaseConnStr"].ConnectionString;
}
internal string SP_GET { get; set; }
internal SqlConnection m_openConn {
get {
var obj = new SqlConnection(connStr);
obj.Open();
return obj;
}
}
internal virtual T FillDataRecord(IDataRecord record) {
return new T();
}
internal TList<T> Get() {
if (String.IsNullOrEmpty(SP_GET)) {
throw new NotSupportedException(string.Format("Get Procedure does not exist for {0}.", typeof(T)));
}
var list = new TList<T>();
using (var cmd = new SqlCommand(SP_GET, m_openConn)) {
cmd.CommandType = cmd.GetCommandTextType();
using (var r = cmd.ExecuteReader()) {
while (r.Read()) {
list.Add(FillDataRecord(r));
}
}
cmd.Connection.Close();
}
return list;
}
}
还有更多,但这应该足够一个例子。
TList 只是一个List<T>
类:
internal class TList<T> : List<T> {
public TList() { }
}
当我的一个类继承它时,我希望它能够覆盖基类的FillDataRecord(IDataRecord)
。
例如, EmployeeDB **继承** DAL_BASE 。
当我致电EmployeeDB.GetEmployeeList()
时,它会使用 DAL_BASE 来提取记录:
public class EmployeeDB : DAL_Base<Employee> {
private static EmployeeDB one;
static EmployeeDB() {
one = new EmployeeDB() {
SP_GET = "getEmployeeList",
};
}
private EmployeeDB() { }
internal override Employee FillDataRecord(IDataRecord record) {
var item = base.FillDataRecord(record);
item.Emp_Login = record.Str("Emp_Login");
item.Emp_Name = record.Str("Emp_Name");
item.Emp_Email = record.Str("Emp_Email");
item.Emp_Phone = record.Str("Emp_Phone");
item.Emp_Role = record.Str("Emp_Role");
return item;
}
public static EmployeeList GetEmployeeList() {
var list = new EmployeeList();
list.AddRange(one.Get());
return list;
}
}
在上面的代码中,当GetEmployeeList()
调用 DAL_Base 方法Get()
时,只会调用 DAL_Base :: FillDataRecord(IDataRecord)。< / p>
我真的需要调用 EmployeeDB :: FillDataRecord(IDataRecord),但我无法使 DAL_Base :: FillDataRecord(IDataRecord)抽象。
解决这个问题的方法是什么?
我现在所知道的就是创建一个EventHandler
,这正是我刚才想到的,所以我会为此努力。
如果有人知道更好的路线,请加入!
答案 0 :(得分:1)
一种解决方案是通过构造函数将Derived.FillDataRecord的委托传递给基类。
public class DAL_Base<T> where T : IDisposable, new() {
private string connStr;
public DAL_Base() {
connStr = ConfigurationManager.ConnectionStrings["CompanyDatabaseConnStr"].ConnectionString;
}
private Func<IDataRecord, T> _fillFunc;
public DAL_Base(Func<IDataRecord, T> fillFunc) : this() {
_fillFunc = fillFunc;
}
// ...
internal TList<T> Get() {
if (String.IsNullOrEmpty(SP_GET)) {
throw new NotSupportedException(string.Format("Get Procedure does not exist for {0}.", typeof(T)));
}
var list = new TList<T>();
using (var cmd = new SqlCommand(SP_GET, m_openConn)) {
cmd.CommandType = cmd.GetCommandTextType();
using (var r = cmd.ExecuteReader()) {
while (r.Read()) {
list.Add(_fullFunc(r));
}
并在派生类中:
public class EmployeeDB : DAL_Base<Employee> {
public EmployeeDB() : base(r => FillDataRecord(r)) { }
private Employee FillDataRecord(IDataRecord record) {
var item = base.FillDataRecord(record);
item.Emp_Login = record.Str("Emp_Login");
item.Emp_Name = record.Str("Emp_Name");
item.Emp_Email = record.Str("Emp_Email");
item.Emp_Phone = record.Str("Emp_Phone");
item.Emp_Role = record.Str("Emp_Role");
return item;
}
}