如何将数据读取器值从 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层中的数据读取器对象。

如何将数据读取器值从 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;
    }
 }
}

将是更好的方法。

我认为你的架构有问题;

  1. 正在使用具体的类来查询数据库;相反,您需要一个抽象,以防您更改后端 SQL Server 或查询机制。

  2. 您正在将混凝土SqlDataReader传递到所有图层中。从 DAL 中,您需要返回数据对象,而不是数据库操作上下文实例。

  3. 您只需要更改层之间的域对象,而不需要更改执行实际工作的对象。

我建议你参考微软西班牙的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())
{
}