0

我在 C# 中使用 N tiers tec 进行工作,试图使其易于使用并且能够更改任何数据库类型而无需重新编写所有 cod,我的代码在这里没有出现任何错误,但它没有得到我的文本框的任何值
(我试图从表中获取数据到许多文本框以便稍后更新它)以及代码的工作原理:{ 首先,我创建了一些函数来获取任何设置的任何类型的参数或设置任何命令,然后我创建其他函数来执行我设置或从数据库中获取的所有函数我在文件夹名称中构建它(数据访问层)然后我创建了其他文件夹(数据构建层)来使用所有这些功能来完成我想要在任何页面中执行的操作(插入、更新、删除、选择),最后我认为我这样做是为了调用我在(数据构建层)到我的页面或控件,我这样做是因为如果我更改数据库类型,我只更改一个类,其他类仍然相同我希望我解释得足够多(抱歉我的英语不够好)}

代码 :

类 DataAccessLayer

public static void Setcommand (SqlCommand cmd,CommandType type,string commandtext)
{
    cmd.CommandType=type;
    cmd.CommandText=commandtext;

}



public static void AddSQLparameter(SqlCommand cmd, int size,SqlDbType type,object value,string paramName,ParameterDirection direction)
{
    if (cmd == null)
{
     throw (new ArgumentException("cmd"));
}

    if (paramName == null)
{
     throw (new ArgumentException("paramName"));
}
    SqlParameter param=new SqlParameter();
    param.ParameterName= paramName;
    param.SqlDbType=type;
    param.Size=size;
    param.Value=value;
    param.Direction=direction;
    cmd.Parameters.Add(param);
}



public static SqlDataReader ExecuteSelectCommand(SqlCommand cmd)
{
    if (cmd == null)
    {
        throw (new ArgumentNullException("cmd"));
    }
    SqlConnection con = new SqlConnection();
    cmd.Connection = con;
    con.Open();
    SqlDataReader dr = cmd.ExecuteReader();
    con.Close();        
    return dr ;

}

类 DatabuildLayer

SqlCommand com;
public DatabuildLayer()
{
  com = new SqlCommand();
  //
  // TODO: Add constructor logic here
  //
}
public SqlDataReader SelectCatalog(int catid)
{
   DataAccessLayer.Setcommand(com, CommandType.Text, "select    catname,catdescription,photo from category where catid=@catid" );
     DataAccessLayer.addSQLparameter(com,16,SqlDbType.Int,catid,"@catid",ParameterDirection.Input);

    return DataAccessLayer.ExecuteSelectCommand(com);;
}

这是我最后一个将数据检索到某个文本框的代码

在我的页面加载中:

 protected void Page_Load(object sender, EventArgs e)
    {
        DatabuildLayer= new DatabuildLayer();
        SqlDataReader dr ;
         dr = obj.SelectCatalog(catselectddl.SelectedIndex);
         if (dr.Read())
         {
             catnametxt.Text = dr["catname"].ToString();
             catdestxt.Text = dr["catdescription"].ToString();
         }
    }
4

3 回答 3

1

您当前的包装器代码没有做任何特别有用的事情(只是替换现有方法或您自己的方法做同样的事情),并且它没有正确关闭连接。这……有点乱。

如果您对原始 ADO.NET 接口还不是很熟悉,那么可以考虑使用类似“ dapper ”的东西,它会为您完成所有这些工作,并使用一个健全的API:

short catid = 16;
using(var conn = GetOpenConnection()) {
    var row = conn.Query(
        "select catname,catdescription,photo from category where catid=@catid",
        new { catid }).FirstOrDefault();
    if(row != null) {
        string name = row.catname, desc = row.catdescription;
        // ...
    }
}

或者,如果您有一个具有 CatName / CatDescription 属性的类:

    var obj = conn.Query<Catalogue>(
        "select catname,catdescription,photo from category where catid=@catid",
        new { catid }).FirstOrDefault();
于 2012-06-02T06:22:14.943 回答
1

查询是否有可能没有返回任何内容,而 dr.Read() 是否返回 false?假设代码实际执行(从这里很难判断),这可能是唯一会阻止它工作的东西 - 无论是那个还是空列。

值得我认为,您的代码需要从结构和约定的角度进行一些整理。您可能应该查看您的代码并考虑 .NET 框架的命名准则。当其他人阅读您的代码时,他们会希望它的格式与本文档一致。http://msdn.microsoft.com/en-us/library/xzf533w0(v=vs.71).aspx

此外,现在大多数使用 ASP.NET 的人都在尝试寻找某种方法来将外部依赖项(例如数据库)注入到他们的代码中,使用像 http://webformsmvp.com/上提供的 WebFormsMVP 这样的框架以及像IoC 这样的容器autofac 可在http://code.google.com/p/autofac/ 获得

使用这种方法,您可以将所有外部依赖项从接口后面的应用程序中推出,这使得插入不同的数据库引擎变得相当简单。

于 2012-06-02T00:45:22.533 回答
0

根据我的经验,当您关闭与 DataReader 关联的连接时,无法再从阅读器中检索任何内容。

//You closed the connection before returning the dr in the your method below:
public static SqlDataReader ExecuteSelectCommand(SqlCommand cmd)
{
   if (cmd == null)
   {
       throw (new ArgumentNullException("cmd"));
   }
   SqlConnection con = new SqlConnection();
   cmd.Connection = con;
   con.Open();
   SqlDataReader dr = cmd.ExecuteReader();
   con.Close();  //here your connection was already closed
   return dr ;   //this dr is disconnected
}
于 2012-06-02T02:49:51.613 回答