3

我正在开发一个使用 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;
    }
}

在演示层上,我在页面加载时写了这个

HomeBAL HBAL = new HomeBAL();
SqlDataReader dr = HBAL.DefaultSearchFriends(user_id);
while (dr.Read())
{ 
 //some code
}

现在我想知道两件事

1-这是以这种方式调用数据读取器的权利还是有一些更好的逻辑。

2-如何在 BAL 层和 DAL 层关闭数据读取器对象。

4

3 回答 3

4

嗯,分层架构的基本思想是将不同的组件解耦,原因有几个。一些原因是可测试性、可维护性、可扩展性,但还有更多。

要在这些层之间传递数据——这在一定程度上取决于数据的类型——但通常你会使用一些简单的类作为数据传输对象 (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;
    }
 }
}

将是更好的方法。

于 2013-01-24T13:23:11.727 回答
0

我认为你的架构有问题;

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

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

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

建议你参考微软西班牙的n层参考应用

于 2013-01-24T13:23:11.393 回答
0

在 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())
{
}
于 2013-01-25T11:02:03.233 回答