C# 如何将datareader值从DAL传递到表示层
我正在从事一个使用三层体系结构的项目。 我想了解一下如何将datareader值从DAL传递到表示层 我的代码是这样的。 在DAL层中C# 如何将datareader值从DAL传递到表示层,c#,asp.net,3-tier,C#,Asp.net,3 Tier,我正在从事一个使用三层体系结构的项目。 我想了解一下如何将datareader值从DAL传递到表示层 我的代码是这样的。 在DAL层中 public class HomeDAL { public SqlDataReader DefaultSearchFriends(long userid) { SqlConnection SocialConn = new SqlConnection(connstr); using (SqlCommand comm = new SqlComm
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-以这种方式调用datareader是正确的还是有更好的逻辑
2-如何关闭BAL层和DAL层中的datareader对象。我认为您的体系结构存在问题
SqlDataReader
传递到所有层中。从DAL中,您需要返回数据对象,而不是db操作上下文实例我建议您参考好吧,分层体系结构的基本思想是将不同的组件解耦,原因有几个。 一些原因是可测试性、可维护性和可扩展性,但还有很多其他原因 要在这些层之间传递数据——这有点取决于数据的类型——但通常您会使用一些简单的类作为数据传输对象(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;
}
}
}
公共类HomeDAL
{
公共列表DefaultSearchFriends(长用户ID)
{
SqlConnection-SocialConn=新的SqlConnection(connstr);
使用(SqlCommand comm=newsqlcommand(“proc_FriendsSearch”,SocialConn))
{
comm.CommandType=CommandType.StoredProcess;
comm.Parameters.AddWithValue(“@userid”,userid);
SocialConn.Open();
SqlDataReader dr=comm.ExecuteReader(CommandBehavior.CloseConnection);
var persons=新列表();
while(dr.Read())
添加(新人物{Name=dr[“Name”],FirstName=dr[“FirstName”]});
Close博士();
返回人员;
}
}
}
将是更好的方法。在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())
{
}
谢谢,先生,你能给我举个好例子解释一下吗。如果你参考我提供的链接,这里有详细的解释。这里要解释的时间太长了(有很多概念,你需要根据你的需要决定使用还是不使用)。谢谢你,伙计,我知道我的体系结构包含问题。但现在我想纠正这些错误。请在我向您展示代码的同时向我展示解决方案。在DAL和BLL文件中要做什么。谢谢你,伙计,但是你现在能给我一个正确的解决方案吗?如何使用sqldatareader。我向你展示我的架构,我知道它有问题。但现在我该如何纠正这些错误呢。请在我向您展示代码的同时向我展示解决方案。DAL和BLL中要做什么file@ankitGupta:我不确定,为什么在我们的解释之后你看不到解决方案,但是请看我的编辑。@ankitGupta:如果它对你有效,那么它没有错。但是考虑到分层体系结构,这是完全错误的,因为您没有分离任何东西。正如我在上面的文章中所描述的,DAL唯一应该发布的是通过DTO的数据。
SqlDataReader
不是数据,它是一个实现细节,应该对其他层隐藏,以维护此体系结构背后的基本思想。我上面也提到过,好的。我同意你的方法。Thanks@ankitGupta:没问题,不客气。请把我的帖子标记为答案,如果你认为它对你有帮助的话。