65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Azure、TDS、WCF、Silverlight 以及一些问题 - 第二部分 – 数据库访问层

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2009 年 5 月 13 日

CPOL

2分钟阅读

viewsIcon

14389

一个多部分文章的第二部分,我构建了一个项目来显示来自多个 RSS 源的新闻标题,作为一个垂直滚动区域

在本文系列的 第一部分 中,我讨论了应用程序背后的数据库。从后端转向客户端,现在是时候讨论访问数据库并返回数据的代码了。

我有一个标准的类,用于访问数据库。我这里使用的版本是为连接到 SQL Server 而开发的,但只需进行一些小的更改,就可以很容易地适应其他数据库,我已经有一个用于 ODBC 的版本。

public Database(string Connection)
{
    connection = new SqlConnection(Connection);
    InitialiseCommand();
}

public Database(SqlConnection Connection)
{
    connection = Connection;
    InitialiseCommand();
}

public Database()
{
    connection = new SqlConnection();
    InitialiseCommand();
}

上面的代码显示了数据库访问层的构造函数。本质上,构造函数期望传递一个连接、连接字符串或什么也不传递给构造函数。每个函数都会调用另一个函数;InitialiseCommand(),它设置命令对象,如下所示。

private void InitialiseCommand()
{
    try
    {
        if (dbCommand == null)
        {
            dbCommand             = new SqlCommand();
            dbCommand.CommandType = CommandType.StoredProcedure;  // default to Stored Prc

            if (connection != null)
            {
                dbCommand.Connection = connection;
            }
        }
    }
    catch (System.Exception ex)
    {
        throw ex;
    }
}

这会初始化 Command 对象并将类型设置为存储过程。如果 Connection 对象已初始化,则 command 对象的连接将设置为 connection 对象。

要执行存储过程,我们需要两个。一个用于返回 datatable,另一个不返回。

    public void Execute()
    {
        try
        {
            if (dbCommand.Connection.State != ConnectionState.Open) dbCommand.Connection.Open();
            dbCommand.ExecuteNonQuery();
        }
        catch (System.Exception ex)
        {
            throw ex;
        }
    }

    public DataTable Execute(string TableName)
    {
        SqlDataAdapter  da;
        DataSet         ds;
        DataTable       dt = new DataTable();

        try
        {
            da = new SqlDataAdapter(dbCommand);
            ds = new DataSet();
            da.Fill(ds,TableName);

            if (ds.Tables.Count > 0)
                dt = ds.Tables[0];
        }
        catch (System.Exception ex)
        {
            throw ex;
        }

        return dt;
    }
}

这两种方法中的第一个比较简单。本质上,它所做的是确认连接是否打开,如果未打开,则打开连接。然后它执行存储过程。整个过程都包含在 try catch 块中,该块会抛回给调用应用程序。

第二个方法更有趣。它使用数据适配器和数据集来填充返回给调用程序的表。

这两种方法涵盖了我可能想要执行的所有类型的数据库操作。

然而,真正的魔力在于从该类继承的类。

public class NewsMashupDB : Database,IDisposable

该类继承自上述代码中定义的类。对象的构造函数如下

public NewsMashupDB() 
    : base()
{
    
}

public NewsMashupDB(string ConnectionString) 
    : base(ConnectionString)
{

}

就是这样。这里有两个 – 一个初始化连接字符串,另一个不初始化。调用应用程序需要做的就是检索连接字符串。执行存储过程同样简单。这里,我们有一个执行 CreateStory 存储过程的存储过程

public void CreateStory(string Headline, string Description, 
                        string Url, string Supplier, long PubDateValue)
{
    SqlParameter paramHeadline      = new SqlParameter("Headline", SqlDbType.VarChar);
    SqlParameter paramDescription   = new SqlParameter("Description",SqlDbType.VarChar);
    SqlParameter paramUrl           = new SqlParameter("Url",SqlDbType.VarChar);
    SqlParameter paramSupplier      = new SqlParameter("Supplier", SqlDbType.VarChar);
    SqlParameter paramPubDate       = new SqlParameter("PubDateValue", SqlDbType.BigInt);

    CommandText = "NewsMashup.CreateStory";

    try
    {
        paramHeadline.Value = Headline;
        paramDescription.Value = Description;
        paramUrl.Value = Url;
        paramSupplier.Value = Supplier;
        paramPubDate.Value = PubDateValue;

        dbCommand.Parameters.Clear();

        dbCommand.Parameters.Add(paramHeadline);
        dbCommand.Parameters.Add(paramDescription);
        dbCommand.Parameters.Add(paramUrl);
        dbCommand.Parameters.Add(paramSupplier);
        dbCommand.Parameters.Add(paramPubDate);

        Execute();
    }
    catch (System.Exception ex)
    {
        throw ex;
    }
}

除了设置存储过程执行所需的参数之外,存储过程的执行只需要两行代码;一行用于初始化命令文本,另一行用于执行存储过程。

返回数据的存储过程同样简单。

public DataTable RetrieveNewsFeeds()
{
    DataTable dt = new DataTable();

    try
    {
        CommandText = "NewsMashup.RetrieveNewsFeeds";

        dt = Execute("NewsFeeds");

    }
    catch (System.Exception ex)
    {
        throw ex;
    }

    return dt;
}

这里比另一种方法更清晰,同样只有两行代码;一行用于初始化 CommandText,另一行用于执行存储过程。此版本的 Execute 返回包含存储过程执行结果的 datatable

这显示了代码示例。其余内容应该在附带的 zip 文件中。

© . All rights reserved.