我有一堆DAO类为实体做类似的事情。 我想知道是否有人可以帮助我: 1)简化此代码 2)停止为每个实体复制这样的代码。
public IList<IUser> GetAll()
{
IList<IUser> users = new List<IUser>();
using (var myConnection = new SqlConnection(ApplicationConfig.ConnectionString))
{
using (var myCommand = new SqlCommand("sp_GetAllUsers", myConnection))
{
myCommand.CommandType = CommandType.StoredProcedure;
myConnection.Open();
using (SqlDataReader myReader = myCommand.ExecuteReader())
{
if (myReader != null)
{
while (myReader.Read())
users.Add(FillDataRecord(myReader));
myReader.Close();
}
}
}
myConnection.Close();
}
return users;
}
public IUser GetBy(int id)
{
IUser user = null;
using (var myConnection = new SqlConnection(AppConfiguration.ConnectionString))
{
using (var myCommand = new SqlCommand("sp_GetUserById", myConnection))
{
myCommand.Parameters.Add("@id", System.Data.SqlDbType.Int).Value = id;
myCommand.CommandType = CommandType.StoredProcedure;
myConnection.Open();
using (SqlDataReader myReader = myCommand.ExecuteReader())
{
if (myReader != null)
{
while (myReader.Read())
user = FillDataRecord(myReader);
myReader.Close();
}
}
}
myConnection.Close();
}
return user;
}
private static IUser FillDataRecord(IDataRecord myDataRecord)
{
IAddress address = null;
if (!myDataRecord.IsDBNull(myDataRecord.GetOrdinal("AddressId")))
address= GetAddress(myDataRecord.GetInt32(myDataRecord.GetOrdinal("AddressId")));
IUser user = new User
{
Id = myDataRecord.GetInt32(myDataRecord.GetOrdinal("Id"))
,LastName = myDataRecord.IsDBNull(myDataRecord.GetOrdinal("LastName")) ? string.Empty : myDataRecord.GetString(myDataRecord.GetOrdinal("LastName"))
,FirstName = myDataRecord.IsDBNull(myDataRecord.GetOrdinal("FirstName")) ? string.Empty : myDataRecord.GetString(myDataRecord.GetOrdinal("FirstName"))
,MyAddress= address
};
return user;
}
提前致谢
答案 0 :(得分:1)
使用泛型和所有数据对象派生自的基类。这是我做的:
using System;
using System.Collections.Generic;
namespace StreamSubServer
{
public abstract class DataObjectBase<T>
{
public List<T> GetAll()
{
//get the value of the StoredProcedureAttribute attribute
}
public T GetBy(int id)
{
...
}
}
[StoredProcedure("usp_GetUsers")]
public class User : DataObjectBase<User>
{
string userName {get;set;}
}
}
然后将椭圆替换为使用反射的实现代码,以遍历数据集/ datareader中返回的列,并将值分配给属性。您可以从ActiveRecord源代码中更好地了解如何执行此操作,我无耻地将其创建为自己的数据访问层。
实现StoredProcedure属性并使用反射检查其值,将其传递到fill方法和chaching中!
祝你好运!答案 1 :(得分:1)
我认为最简单的重构是:
public IList<IUser> GetAll()
{
using (var myConnection = new SqlConnection(ApplicationConfig.ConnectionString))
{
using (var myCommand = new SqlCommand("sp_GetAllUsers", myConnection))
{
return loadUserList(myConnection, myCommand);
}
myConnection.Close(); // This should be in a finally if to be used
}
return null;
}
private IList<IUser> loadUserList(SqlConnection myConnection, SqlCommand myCommand) {
IList<IUser> users = new List<IUser>();
myCommand.CommandType = CommandType.StoredProcedure;
myConnection.Open();
using (SqlDataReader myReader = myCommand.ExecuteReader())
{
if (myReader != null)
{
while (myReader.Read())
users.Add(FillDataRecord(myReader));
myReader.Close();
}
}
return users;
}
如果另一个功能你可以只返回第一个记录,如果你愿意,可以返回自IUser以来。
为了使这更通用,传入一个动作来进行处理,因此每个实体都可以负责它自己的解析,并使用已经提到的泛型。