如何将数据读取器值从 DAL 传递到表示层
本文关键字:DAL 表示层 数据 读取 | 更新日期: 2023-09-27 17:56:03
我正在开发一个使用 3 层架构的项目。我想了解如何将数据读取器值从 DAL 传递到表示层
我的代码是这样的。在 DAL 层中
public class HomeDAL
{
public SqlDataReader DefaultSearchFriends(long userid)
{
SqlConnection SocialConn = new SqlConnection(connstr);
using (SqlCommand comm = new SqlCommand("proc_FriendsSearch", SocialConn))
{
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("@userid", userid);
SocialConn.Open();
SqlDataReader dr = comm.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}
}
}
在 BAL 层中
public class HomeBAL
{
public SqlDataReader DefaultSearchFriends(long userid)
{
HomeDAL HDAL = new HomeDAL();
SqlDataReader dr = HDAL.DefaultSearchFriends(userid);
return dr;
}
}
在 Presentaion 层上,我在页面加载时写了这个
HomeBAL HBAL = new HomeBAL();
SqlDataReader dr = HBAL.DefaultSearchFriends(user_id);
while (dr.Read())
{
//some code
}
现在我想知道两件事
1-以这种方式调用数据读取器是正确的,还是有一些更好的逻辑。
2-如何关闭BAL层和DAL层中的数据读取器对象。
嗯,分层架构的基本思想是出于几个原因将不同的组件解耦。一些原因是可测试性、可维护性、可扩展性,但还有更多。
要在这些层之间传递数据 - 这有点取决于数据类型 - 但通常你会使用一些简单的类作为数据传输对象(DTO),这些类将在DAL中填充数据。
public class Person
{
public string Name {get; set;}
public string FirstName {get; set;}
...
}
通过您的方法,您正在打破这个想法,因为您将DataReader
传递给表示层,这意味着您无法在不接触其他层的情况下切换 DAL 技术。 例如,如果要使用实体框架,则必须修改代码中的每个部分,其中您当前正在使用SqlDataReader
。
你也可以看到,如果你坚持分层方法背后的想法,你不必考虑你的第二个问题。
我希望这有所帮助。
编辑
好吧,我有点好奇,你没有找到合适的解决方案。但无论如何,第一个也是最简单的方法可能是, 不要发布SqlDataReader
.在 DAL 中处理其生命周期。意味着,假设您使用的是上面的DTO
public class HomeDAL
{
public List<Person> DefaultSearchFriends(long userid)
{
SqlConnection SocialConn = new SqlConnection(connstr);
using (SqlCommand comm = new SqlCommand("proc_FriendsSearch", SocialConn))
{
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("@userid", userid);
SocialConn.Open();
SqlDataReader dr = comm.ExecuteReader(CommandBehavior.CloseConnection);
var persons = new List<Person>();
while (dr.Read())
persons.Add(new Person { Name = dr["Name"], FirstName = dr["FirstName"] });
dr.Close();
return persons;
}
}
}
将是更好的方法。
我认为你的架构有问题;
- 您
正在使用具体的类来查询数据库;相反,您需要一个抽象,以防您更改后端 SQL Server 或查询机制。
您正在将混凝土
SqlDataReader
传递到所有图层中。从 DAL 中,您需要返回数据对象,而不是数据库操作上下文实例。您只需要更改层之间的域对象,而不需要更改执行实际工作的对象。
我建议你参考微软西班牙的n层参考应用
在 DAL 文件中
public class HomeDAL
{
public void DefaultSearchFriends(ref HomeBAL hBAL)
{
SqlConnection SocialConn = new SqlConnection(connstr);
using (SqlCommand comm = new SqlCommand("proc_FriendsSearch", SocialConn))
{
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("@userid", hBAL.userid);
SocialConn.Open();
hBAL.Search_Reader = comm.ExecuteReader(CommandBehavior.CloseConnection);
}
}
}
在 BAL 文件中
public class HomeBAL
{
public SqlDataReader Search_Reader = null;
}
和在呈现层中
HomeBAL HBAL = new HomeBAL();
HomeDAL HDAL = new HomeDAL();
HDAL.DefaultSearchFriends(ref HBAL);
SqlDataReader dr = HBAL.Search_Reader;
while (dr.Read())
{
}