使用静态DataSet作为DataSource

时间:2011-02-28 13:03:17

标签: c# winforms dataset visual-c#-express-2010

在我的应用程序中,我有一个DataSet,它包含在我的应用程序中以不同形式使用的表。 为了能够维护表单之间的并发性,并且每次用户打开新表单时都不必从数据库中获取数据,我将DataSet作为静态字段保存在程序类中,如下所示:

static class Program
{
    public static CustomDataSet StockDataSet { get; private set; }

    [STAThread]
    static void Main()
    {
        StockDataSet = new Database.CustomDataSet();
        StockDataSet.InitRelations();
        StockDataSet.EnforceConstraints = false;
        StockDataSet.Categories.Fill();
        StockDataSet.Suppliers.Fill();
        StockDataSet.StockItems.Fill();
        StockDataSet.EnforceConstraints = true;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainWindow());
    }

这使得以编程方式使用DataSet非常容易。然而,在设计时工作会导致分配挫折。为了考试;我有一个绑定到BindingSource的DataGridView表单。如果我希望能够在设计时使用DataGridView的列,我必须有一个可以访问InitializeComponent中BindingSource的自定义DataSet的对象。

我能想到的所有解决方法都是非常丑陋的黑客攻击。 就像在Designer.cs中使用虚拟对象来保持设计时间一样,然后将静态对象分配给持有虚拟对象的字段。然后重置构造函数中的所有绑定。这必须被视为非常糟糕的做法,对吗?

所以我的问题是:这是不是更优雅,或者至少是实用的方法? 或者是否有任何建议的以多种形式使用DataSet的最佳实践?

修改
库存是指库存中的库存。没有对数据进行繁重处理,数据保存在本地服务器上的MySql数据库中。

3 个答案:

答案 0 :(得分:2)

在运行时显示一个DataSource,而在DesignTime中显示其他数据源并不难看。我认为在使用DataTables,DataSet和DataGridViews以及设计器时,您正在使用的内容相当普遍。如果使用非常简单的主/表单形式并且不希望超出标准行为,那么它是一个很好的工具。

在您描述的方案中,您希望更改这些项目的正常使用情况,以便在应用程序启动时预加载数据。正如您所知,这会导致您现在必须自己处理的一些问题。处理该问题的一部分是在运行时将DataSource重置为新值。这根本不是不优雅或不好的做法。

然而,当你开始谈论假货和由于性能问题而进行的缓存时,我想知道你是否真的想要一个数据库。您似乎希望开发一个可以根据需要绑定,更新和序列化的模型(使用C#对象)。虽然我不确定你的设计是否属实,但如果是我的设计(我对你的问题的理解有限)那就是我要做的事情。如果有的话,数据库在这一点上不会成为我项目的重要组成部分。我将构建代表我的表的C#对象,管理这些项的模型类,以及实例化模型并管理其生命周期的工厂。

如果在某些时候,我已经序列化/与数据库进行交互,我会将其构建到模型中。

对于我来说,关于优雅的一个更大的问题是,我将如何测试所有这些?如果我在设计时绑定,并依赖静态加载运行时,那么我的设计阻止我执行任何类型的单元或基于类的集成测试。如果我将数据库内容分离到一个模型中,那么我会将数据管理的关注分成一个我可以粘贴接口的类,这给了我一些伪造或模拟和存根的东西。

答案 1 :(得分:0)

我想在Designer.cs中使用虚拟对象,但是使用条件编译来评论相应的部分(即#if DEBUG)

答案 2 :(得分:0)

尝试使用单例设计模式。

public sealed class DB
{
    private static readonly DB instance = new DB( );
    public static DB Instance { get { return instance; } }

    static DB( ) { }
    private DB( ) 
    {
        StaticData = new DataSet( );
    }

    private static DataSet StaticData;

    public DataTable GetCategoryTable( )
    {
        // check if the table has been created
        if( StaticData.Tables["Category"] == null )
        {
            // build table (or retrieve from database)
            DataTable table = new DataTable( );
            table.TableName = "Category";
            table.Columns.Add( "ID", typeof( int ) );
            table.Columns.Add( "Name", typeof( string ) );
            table.Columns.Add( "Description", typeof( string ) );

            table.Rows.Add( 1, "Beverages", "Soft drinks, coffees, teas, beers, and ales" );
            table.Rows.Add( 2, "Condiments", "Sweet and savory sauces, relishes, spreads, and seasonings" );
            table.Rows.Add( 3, "Produce", "Dried fruit and bean curd" );
            table.Rows.Add( 4, "Seafood", "Seaweed and fish" );
            table.Rows.Add( 5, "Meat/Poultry", "Prepared meats" );
            StaticData.Tables.Add(table.Copy());

        }
        return StaticData.Tables["Category"];   
    }

    public DataTable GetStatusTable( )
    {
        // check if the table has been created
        if( StaticData.Tables["Status"] == null )
        {
            // build table (or retrieve from database)
            DataTable table = new DataTable( );
            table.TableName = "Status";
            table.Columns.Add( "ID", typeof( int ) );
            table.Columns.Add( "Name", typeof( string ) );
            table.Columns.Add( "Description", typeof( string ) );

            table.Rows.Add( 1, "Active", "Active" );
            table.Rows.Add( 2, "Retired", "Retired" );
            StaticData.Tables.Add( table.Copy( ) );

        }
        return StaticData.Tables["Status"];
    }

}

像这样使用:

    private void Form1_Load( object sender, EventArgs e )
    {
        DB db = DB.Instance;
        dataGridView1.DataSource = db.GetCategoryTable( );
        dataGridView2.DataSource = db.GetCategoryTable( );
        dataGridView3.DataSource = db.GetStatusTable( );
    }