将数据访问代码分成不同的层

时间:2014-10-15 03:55:40

标签: c# asp.net ado.net 3-tier

我正在尝试将此功能分为传统的3层模式,但遇到一些困难。

数据访问不是我经常使用的东西,我想要一些指导。

我从code from this blog开始,到目前为止我所做的工作如下。我正在将返回类型转换为SqlDataReader,现在我已经注释掉了需要分离的代码。

// This is the DAL layer:
public SqlDataReader DownloadFile(int fileId)
{
    //int id = int.Parse((sender as LinkButton).CommandArgument);
    //byte[] bytes;
    //string fileName, contentType;
    //string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    //using (SqlConnection con = new SqlConnection(constr))
    //{
        cmd.CommandText = "SELECT  [fileId],[fileName],[fileData],[postedBy] FROM  [dbo].[FilesLibrary] where fileId=@Id";
        cmd.Parameters.AddWithValue("@Id", fileId);
        cmd.Connection = cmd.Connection;

        try
        {
            cmd.Connection.Open();

            using (SqlDataReader sdr = cmd.ExecuteReader())
            {
                //sdr.Read();
                //bytes = (byte[])sdr["Data"];
                //contentType = sdr["ContentType"].ToString();
                //fileName = sdr["Name"].ToString();
                return sdr;
            }
        }
        catch (Exception ex)
        {
            cmd.Connection.Close();
            throw;
        }
    //}
    //Response.Clear();
    //Response.Buffer = true;
    //Response.Charset = "";
    //Response.Cache.SetCacheability(HttpCacheability.NoCache);
    //Response.ContentType = contentType;
    //Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
    //Response.BinaryWrite(bytes);
    //Response.Flush();
    //Response.End();
}

// The BL is below:        
public SqlDataReader GetFileDownload(int fileId)
{
    try
    {
        dsGetFiles files = new dsGetFiles();
        return files.DownloadFile(fileId);
    }
    catch (Exception ex) { throw ex; }
}

// The code file is as follows:
protected void DownloadFile(object sender, EventArgs e)
{
    int id = int.Parse((sender as LinkButton).CommandArgument);
    byte[] bytes;
    string fileName, contentType;

    GetFiles fileInfo = new GetFiles();
    fileInfo.GetFileDownload(id);

    // Here I don't know what to do with the fileInfo object and how to get data out of it.
    //sdr.Read();
    //bytes = (byte[])sdr["fileData"];
    //contentType = sdr["ContentType"].ToString();
    //fileName = sdr["fileName"].ToString();


    Response.Clear();
    Response.Buffer = true;
    Response.Charset = "";
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.ContentType = contentType;
    Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
    Response.BinaryWrite(bytes);
    Response.Flush();
    Response.End();
}

1 个答案:

答案 0 :(得分:1)

// This is the DAL layer:
public DataSet DownloadFile(int fileId)
{
    //I don't know from where you are taking your command and connection, but I will assume that this is working correctly, I don't like this method ! Also close a connection only on catch block? Your are using only one connection ? If you tell me that this method is not working I will re write it too. 

cmd.CommandText = "SELECT  [fileId],[fileName],[fileData],[postedBy] FROM  [dbo].[FilesLibrary] where fileId=@Id";
cmd.Parameters.AddWithValue("@Id", fileId);
cmd.Connection = cmd.Connection;

try
{
    cmd.Connection.Open();

    DataSet dst = new DataSet();
    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
    {
        adapter.Fill(dst, "FilesLibary");        
    }

    return dst;
}
catch (Exception ex)
{
    cmd.Connection.Close();
    throw;
}


}

// The BL is below:        
public byte[] GetFileDownload(int fileId)
{
    try
    {
        DataSet fileDst = new DownloadFile();// method from DA layer
        return (byte[])fileDst.Tables[0].Rows[0]["fileData"];
    }
    catch (Exception ex) { throw ex; }
}



protected void DownloadFile(object sender, EventArgs e)
{
    int id = int.Parse((sender as LinkButton).CommandArgument);
    byte[] bytes = fileInfo.GetFileDownload(id);

//Now do your magic, if you want to have fileName in the business logic you should take GetFileDownload should return DataSet. After that take byte[] and fileName. I will write the fileName to be test for this case to not re write everything here !

Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=Test");
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}

请注意:您的DataAccess层非常糟糕。你应该重写它。就像我在DataLayer中更改方法后看到的那样,您甚至不需要BO逻辑方法,因为您的数据层将重新运行所需的DataSet,您可以调用protected void DownloadFile(object sender, EventArgs e)

在这个问题中,我写了一些完整的数据层类,如果你想要的话可​​以检查checking user name or user email already exists

PS。很抱歉打开和结束括号格式化问题!