Использование статического набора данных в качестве источника данных - PullRequest
2 голосов
/ 28 февраля 2011

В моем приложении у меня есть 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 программно.Работа во время разработки, однако, вызывает много разочарований.Для экзамена;У меня есть форма с DataGridView, связанной с BindingSource.Если я хочу иметь возможность работать со столбцами DataGridView во время разработки, у меня должен быть объект моего пользовательского DataSet, доступный для BindingSource в InitializeComponent.

Все обходные пути для этого я могу придуматьдовольно уродливые хаки.Например, использование фиктивного объекта в Designer.cs для поддержания времени разработки, а затем назначение статического объекта полю, содержащему фиктивный объект.И после этого сбросьте все привязки в конструкторе.Это должно считаться очень плохой практикой, верно?

Так что мой вопрос таков: Разве нет более элегантного или хотя бы практического подхода к этому?Или есть какие-либо рекомендуемые рекомендации по работе с наборами данных в нескольких формах?

Редактировать
Запас относится к хранению запаса как к инвентарю.Для данных не выполняется тяжелая обработка, которая хранится в базе данных MySql на локальном сервере.

Ответы [ 3 ]

2 голосов
/ 28 февраля 2011

Отображение одного источника данных во время выполнения, а другого в DesignTime совсем не страшно. Я думаю, что то, с чем вы боретесь, довольно распространено, когда используются DataTables, DataSets, DataGridViews и дизайнер. Это отличный инструмент, если вы работаете с очень простыми формами Master / Detail и не хотите выходить за рамки стандартного поведения.

В описанном вами сценарии вы хотите изменить обычное использование этих элементов, чтобы можно было предварительно загружать данные при запуске приложения. Как вы узнали, это вызывает некоторые проблемы, с которыми вам теперь придется справиться самостоятельно. Частью решения этой проблемы является сброс DataSource к новому значению во время выполнения. Это совсем не безумие или плохая практика.

Однако, когда вы начинаете говорить о подделках и кешировании из-за проблем с производительностью, я задаюсь вопросом, действительно ли вам вообще нужна база данных. Похоже, вы хотите разработать модель (используя объекты C #), которую вы можете привязывать, обновлять и сериализовать по мере необходимости. Хотя я не уверен, что это верно для вашего дизайна, если бы это был мой дизайн (с моим ограниченным пониманием вашей проблемы), это было бы то, чем я бы занимался. База данных не будет большой частью моего проекта на данный момент, если вообще. Я бы построил объекты C #, которые представляют мои таблицы, класс модели для управления этими элементами и фабрику для создания экземпляра модели и управления ее временем жизни.

Если бы в какой-то момент у меня было для сериализации / взаимодействия с / с базой данных, я бы встроил это в модель.

Большой вопрос для меня в отношении элегантности: как бы я все это проверил? Если я привязываюсь во время разработки и полагаюсь на статическую загрузку во время выполнения, тогда моя конструкция не позволяет мне выполнять какие-либо модульные или интеграционные тесты на основе классов. Если бы я разделил компоненты базы данных на модель, то я бы разделил задачу управления данными на класс, в который я мог бы вставить интерфейс, что давало бы мне что-то подделать или посмеяться и заглушить.

0 голосов
/ 01 марта 2011

Попробуйте использовать шаблон проектирования Singleton.

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( );
    }
0 голосов
/ 28 февраля 2011

Я бы пошел с идеей использования фиктивного объекта в Designer.cs, но закомментировал соответствующий раздел, используя условную компиляцию (т.е. #if DEBUG)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...