Прогрузка информации с бд на вторичных Window на старте приложения

Собственно, есть два окна, Window и TempWindow. На втором таблица, подгружаемая с бд, конкретно - с MSSQL локально. Второе окно открывается при нажатии кнопки на первом.

И проблема вот в чём - на подгрузку бд при первом открытии окна TempWindow тратится заметная секунда. А при его закрытии и повторном открытии бд отображается мгновенно. Значит, даже при закрытом TempWindow загруженная бд где-то хранится. И значит, её можно загрузить, и не открывая TempWindow, в котором она будет отображена.

То есть хотелось бы уже при запуске основного Window прогрузить все запросы к бд на вторичных окнах, чтобы даже при первом их открытии бд отображалась моментально, а не целую секунду. Как к этому можно подойти?

Ну либо можно как ускорить подгрузку с бд? Секунда - как-то слишком для локальной бд.

Подгрузка в бд написана базово, в TempWindow.xaml.cs:

        SqlDataAdapter adapter;
        DataTable H1Table;

        public TempWindow()
        {
            InitializeComponent();
            connectionString = "server = DESKTOP-1KILEEG; Trusted_Connection = Yes; DataBase = AlgonaDatabase;";
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string sql = "SELECT * FROM dbo.H1";
            H1Table = new DataTable();
            SqlConnection connection = null;
            try
            {
                connection = new SqlConnection(connectionString);
                SqlCommand command = new SqlCommand(sql, connection);
                adapter = new SqlDataAdapter(command);

                // установка команды на добавление для вызова хранимой процедуры
                adapter.InsertCommand = new SqlCommand("sp_InsertH1Section", connection);
                adapter.InsertCommand.CommandType = CommandType.StoredProcedure;
                adapter.InsertCommand.Parameters.Add(new SqlParameter("@HeadingName", SqlDbType.NVarChar, 40, "HeadingName"));       
                SqlParameter parameter = adapter.InsertCommand.Parameters.Add("@Id", SqlDbType.Int, 0, "Id");
                parameter.Direction = ParameterDirection.Output;

                connection.Open();
                adapter.Fill(H1Table);
                H1SectionsGrid.ItemsSource = H1Table.DefaultView;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (connection != null)
                    connection.Close();
            }
        }```

Ответы (1 шт):

Автор решения: aepot

К сожалению, я не знаю про поведение БД, но зато знаю про всё остальное. Например, про привязку данных.

Поменяйте это

<DataGrid x:Name="H1SectionsGrid" .../>

На это

<DataGrid ItemsSource="{Binding H1Table}" .../>

То есть выкинуть имя и привязаться к DataTable, содержащей данные.

Теперь C# код можно переписать вот так с привязкой данных

public partial class TempWindow : Window, INotifyPropertyChanged
{
    private const string connectionString = "server = DESKTOP-1KILEEG; Trusted_Connection = Yes; DataBase = AlgonaDatabase;";
    private DataTable _h1Table; // не обращайтесь к этому полю, обращайтесь к свойству H1Table вместо этого

    public DataTable H1Table
    {
        get => _h1Table; 
        set
        {
            _h1Table = value;
            OnPropertyChanged();
        }
    }

    public TempWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    private async Task LoadDataAsync()
    {
        string sql = "SELECT * FROM dbo.H1";
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            await connection.OpenAsync();
            using (SqlDataAdapter adapter = new SqlDataAdapter(sql, connection))
            using (SqlCommand insertCommand = new SqlCommand("sp_InsertH1Section", connection) { CommandType = CommandType.StoredProcedure })
            {
                insertCommand.Parameters.Add(new SqlParameter("@HeadingName", SqlDbType.NVarChar, 40, "HeadingName"));
                insertCommand.Parameters.Add(new SqlParameter("@Id", SqlDbType.Int, 0, "Id") { Direction = ParameterDirection.Output });
                adapter.InsertCommand = insertCommand;
                DataTable dt = new DataTable();
                await Task.Run(() => adapter.Fill(dt));
                H1Table = dt;
            }
        }
    }

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        try
        {
            await LoadDataAsync();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Фишка привязки в том, что вы можете сколько угодно изменять и переприсваивать H1Table в коде, DataGrid будет обновляться в соответствии с этими изменениями.

Подождать, когда произойдет первое подключение все равно придется, но теперь за счет async/await ваше окно не будет в зависшем состоянии.

Далее, рекомендую вам познакомиться со зверем Entity Framework. Он умеет сам строить SQL запросы, с ним намного удобнее работать, чем с ADO.

→ Ссылка