我在模板模式样式中编写方法时遇到了一些问题。但首先我的代码:
我正在使用的 Base 类如下所示:
public abstract class DbBase<T> where T : new()
{
protected abstract Value CommandValue { get; }
protected abstract CommandType CommandType { get; }
protected abstract Mapper<T> GetMapper();
protected abstract IDbConnection GetConnection();
protected abstract Collection<IDataParameter> GetParameters(IDbCommand command);
public Collection<IDataParameter> Paramaters { get; set; }
#region Public Methods
public T Single(int id)
{
return ExecuteReader(id).SingleOrDefault();
}
public Collection<T> All()
{
return ExecuteReader();
}
#endregion
#region Private Methods
private Collection<T> ExecuteReader(int? id = null)
{
var collection = new Collection<T>();
using (var connection = GetConnection())
{
var command = connection.CreateCommand();
command.Connection = connection;
command.CommandType = CommandType;
if (id.HasValue && id.Value > 0)
command.CommandText = CommandValue.Single;
else
command.CommandText = CommandValue.All;
var parameters = GetParameters(command);
if (parameters != null)
{
foreach (var param in GetParameters(command))
command.Parameters.Add(param);
}
try
{
connection.Open();
using (var reader = command.ExecuteReader())
{
try
{
var mapper = GetMapper();
collection = mapper.MapAll(reader);
return collection;
}
finally
{
if (!reader.IsClosed)
reader.Close();
}
}
}
catch (Exception ex)
{
throw new DbBaseException(ex.Message, ex);
}
finally
{
if (connection.State != ConnectionState.Closed)
connection.Close();
}
}
}
#endregion
}
所以现在对于每一段可能会改变的代码,我都有一个继承的细节类:
public class UserDb : DbBase<User>
{
private static readonly string ALL = "SELECT * FROM [USER]"; //don't use star!
private static readonly string SINGLE = "SELECT * FROM [USER] WHERE USER_ID = @USER_ID";
private static readonly CommandType commandType = CommandType.Text;
protected override Value CommandValue
{
get
{
var value = new Value
{
Single = SINGLE,
All = ALL
};
return value;
}
}
protected override CommandType CommandType
{
get { return commandType; }
}
protected override Mapper<User> GetMapper()
{
return new UserMapper();
}
protected override Collection<IDataParameter> GetParameters(IDbCommand command)
{
var parameters = new Collection<IDataParameter>();
var param = command.CreateParameter();
param.ParameterName = "@USER_ID";
param.Value = 2;
parameters.Add(param);
return parameters;
}
}
调用代码:
var userDb = new UserDb();
var user = userDb.Single(1);
if (user != null)
Console.WriteLine(string.Format("{0}, {1}, {2}", user.UserId, user.Username, user.Password));
正如你所看到的,我已经实现了一个名为 Single 的方法,它通过 id 给我一个特定的行。我的问题是如何在不破坏模板模式的情况下将 id 推送到我的 ExecuteReader 方法中?
我希望你们能帮助我。
谢谢