Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с DataRelation 
V
    Опции темы
Red Wind
Дата 19.8.2006, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Доброго, всем, времени суток!

Скажите как правильно связывать колонки таблиц в DataSet с помощю DataRelation. Потратил на это пол дня, но ничего хорошего из этого не получилосьsmile, пришлось вернуться практически к самому началу...

На форме находится два DataGridView. И мне нужно, что бы все изменения в одном из них, отображались во втором. Вот мой код, чего здесь не хватает?
Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Testing
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

    DataSet ds = new DataSet("test");
        DataTable One = new DataTable("One");
        DataColumn one = new DataColumn("one", Type.GetType("System.String"));

        DataTable Two = new DataTable("Two");
        DataColumn two = new DataColumn("two", Type.GetType("System.String"));

        private void Form1_Load(object sender, EventArgs e)
        {
        one.AllowDBNull = false;
            one.Unique = true;
            two.AllowDBNull = false;
            two.Unique = true;

            One.Columns.Add(one);
            Two.Columns.Add(two);
            ds.Tables.AddRange(new DataTable[] { One, Two });
            dataGridView1.DataSource = ds.Tables["one"];
            dataGridView2.DataSource = ds.Tables["two"];

            DataRelation dr = new DataRelation("test",
               ds.Tables["One"].Columns["one"],
               ds.Tables["Two"].Columns["two"], true);
            ds.Relations.Add(dr);
        }
    }
}

PM MAIL ICQ   Вверх
mr.DUDA
Дата 19.8.2006, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



Две ошибки:

1) в обеих таблицах должен быть назначен Primary Key, и связь между таблицами должна быть по полю, которое в родительской таблице является primary key
2) назначать DataSource для DataGridView нужно не на датасет (!) а на BindingSource, у которого в свою очередь задаётся DataSource и DataMember на наш датасет и таблицу

Добавлено @ 20:25 
З.Ы. пример из MSDN (в проекте только 1 исходник - Form1.cs, надо убрать Program.cs и Form1.Designer.cs/Form1.resx):
Код
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

public class Form1 : System.Windows.Forms.Form
{
    private DataGridView masterDataGridView = new DataGridView();
    private BindingSource masterBindingSource = new BindingSource();
    private DataGridView detailsDataGridView = new DataGridView();
    private BindingSource detailsBindingSource = new BindingSource();

    [STAThreadAttribute()]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    // Initializes the form.
    public Form1()
    {
        masterDataGridView.Dock = DockStyle.Fill;
        detailsDataGridView.Dock = DockStyle.Fill;

        SplitContainer splitContainer1 = new SplitContainer();
        splitContainer1.Dock = DockStyle.Fill;
        splitContainer1.Orientation = Orientation.Horizontal;
        splitContainer1.Panel1.Controls.Add(masterDataGridView);
        splitContainer1.Panel2.Controls.Add(detailsDataGridView);

        this.Controls.Add(splitContainer1);
        this.Load += new System.EventHandler(Form1_Load);
        this.Text = "DataGridView master/detail demo";
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Bind the DataGridView controls to the BindingSource
        // components and load the data from the database.
        masterDataGridView.DataSource = masterBindingSource;
        detailsDataGridView.DataSource = detailsBindingSource;
        GetData();

        // Resize the master DataGridView columns to fit the newly loaded data.
        masterDataGridView.AutoResizeColumns();

        // Configure the details DataGridView so that its columns automatically
        // adjust their widths when the data changes.
        detailsDataGridView.AutoSizeColumnsMode =
            DataGridViewAutoSizeColumnsMode.AllCells;
    }

    private void GetData()
    {
        try
        {
            DataSet data = new DataSet();
            DataTable tableCustomers = data.Tables.Add("Customers");
            tableCustomers.PrimaryKey = new DataColumn[] { tableCustomers.Columns.Add("CustomerID", typeof(int)) };
            tableCustomers.Columns.Add("Name", typeof(string));

            DataTable tableOrders = data.Tables.Add("Orders");
            tableOrders.PrimaryKey = new DataColumn[] { tableOrders.Columns.Add("OrderID", typeof(int)) };
            tableOrders.Columns.Add("Amount", typeof(int));
            tableOrders.Columns.Add("CustomerID", typeof(int));

            // Establish a relationship between the two tables.
            DataRelation relation = new DataRelation("CustomersOrders",
                data.Tables["Customers"].Columns["CustomerID"],
                data.Tables["Orders"].Columns["CustomerID"]);
            data.Relations.Add(relation);

            // Bind the master data connector to the Customers table.
            masterBindingSource.DataSource = data;
            masterBindingSource.DataMember = "Customers";

            // Bind the details data connector to the master data connector,
            // using the DataRelation name to filter the information in the 
            // details table based on the current row in the master table. 
            detailsBindingSource.DataSource = masterBindingSource;
            detailsBindingSource.DataMember = "CustomersOrders";
        }
        catch (SqlException)
        {
            MessageBox.Show("To run this example, replace the value of the " +
                "connectionString variable with a connection string that is " +
                "valid for your system.");
        }
    }
}



--------------------
user posted image
PM MAIL WWW   Вверх
Red Wind
Дата 20.8.2006, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Не, это совсем не то что мене нужно. Но, вроде бы, у меня получилось сделать примерно, то что надо. Только теперь проблема в том, что хочеться реализовать это не используя события RowChanged, а просто отделаться применением DataRelation.

И ещё я так и не понял, зачем здесь использовать BindingSource. Всё хорошо работает и без него. Да и PrimaryKey никак не влияет на работоспособность моего кода. Для чего нужны эти фишки?

А вот, собственно и то, что у меня получилось. Конечно, это ещё черновой вариант, но всё же:

Код


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Testing
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        DataSet ds = new DataSet("test");
        DataTable One = new DataTable("One");
        DataColumn one = new DataColumn("one", Type.GetType("System.String"));

        DataTable Two = new DataTable("Two");
        DataColumn two = new DataColumn("two", Type.GetType("System.String"));

        //BindingSource OneBindingSource = new BindingSource();
        //BindingSource TwoBindingSource = new BindingSource();

        private void button1_Click(object sender, EventArgs e)
        {
            one.AllowDBNull = false;
            one.Unique = true;
            two.AllowDBNull = false;
            two.Unique = true;;

            One.Columns.Add(one);
            Two.Columns.Add(two);

            //One.PrimaryKey = new DataColumn[] { One.Columns["one"] };
            //Two.PrimaryKey = new DataColumn[] { Two.Columns["two"] };

            ds.Tables.AddRange(new DataTable[] { One, Two });

            //OneBindingSource.DataSource = ds.Tables["One"];
            //TwoBindingSource.DataSource = ds.Tables["Two"];

            //dataGridView1.DataSource = OneBindingSource;
            //dataGridView2.DataSource = TwoBindingSource;

            dataGridView1.DataSource = ds.Tables["One"];
            dataGridView2.DataSource = ds.Tables["Two"];

            DataRelation dr = new DataRelation("test",
                ds.Tables["One"].Columns["one"],
                ds.Tables["Two"].Columns["two"], true);
            ds.Relations.Add(dr);

            ds.Tables["One"].RowChanged += new DataRowChangeEventHandler(Form1_RowChanged);
        }

        private void Form1_RowChanged(object sender, DataRowChangeEventArgs e)
        {
            
            if (e.Action == DataRowAction.Add)
            {
                ds.Tables["Two"].Rows.Add(e.Row.ItemArray);
                return;
            }

            if (e.Action == DataRowAction.Change)
            {
                foreach (DataRow ChildRow in e.Row.GetChildRows(ds.Relations["test"]))
                {
                    if (ChildRow.Equals(e.Row))
                        ChildRow.ItemArray = e.Row.ItemArray;
                }
                return;
            }

            if (e.Action == DataRowAction.Delete)
            {
                foreach (DataRow ChildRow in e.Row.GetChildRows(ds.Relations["test"]))
                {
                    if (ChildRow.Equals(e.Row))
                        ChildRow.Delete();
                }
                return;
            }
        }
    }
}




Это сообщение отредактировал(а) Red Wind - 20.8.2006, 16:15
PM MAIL ICQ   Вверх
mr.DUDA
Дата 20.8.2006, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



Цитата(Red Wind @  20.8.2006,  16:14 Найти цитируемый пост)
И ещё я так и не понял, зачем здесь использовать BindingSource. Всё хорошо работает и без него. Да и PrimaryKey никак не влияет на работоспособность моего кода. Для чего нужны эти фишки?

Это нужно только для того, чтобы конкретный контрол DataGridView отслеживал изменения по связанным таблицам. В .NET Framework 1.1 было достаточно замапить DataGrid на связанные таблицы, а в 2.0 уже нужен BindingSource.


--------------------
user posted image
PM MAIL WWW   Вверх
Red Wind
Дата 20.8.2006, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Спасибо, тогда ясно.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.0479 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.