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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> каскадрные действия в DataTable, table = new DataTable("myTable");  
:(
    Опции темы
Compositum
  Дата 21.6.2008, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

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



Если нужна одна таблица - нет смысла создавать датаСет. Мне одна табла и нужна - таблица древа документов. Код:
Код

table = new DataTable("myTable");
            DataColumn id = new DataColumn("ID", typeof(int));
            table.Columns.Add(id);
            table.PrimaryKey = new DataColumn[1] { id };
            id.AutoIncrement = true;
            id.AutoIncrementSeed = 1;
            id.AutoIncrementStep = 1;            
            DataColumn name = new DataColumn("Name", typeof(string));
            table.Columns.Add(name);
            table.Columns["name"].Unique = true;
            DataColumn notes = new DataColumn("Notes", typeof(string));
            table.Columns.Add(notes);
            DataColumn father = new DataColumn("Father", typeof(int));
            table.Columns.Add(father);
            ForeignKeyConstraint foreignkey = new ForeignKeyConstraint(id, father);            
            foreignkey.DeleteRule = Rule.Cascade;
            foreignkey.UpdateRule = Rule.Cascade;
            table.Constraints.Add(foreignkey);

но.... если я удаляю родительскую запись, дочерние остаются, хотя я ясно прописал, что нужно выполнять каскадные действия. Что не так делаю?
PM   Вверх
Idsa
Дата 21.6.2008, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 15
Всего: 62



Цитата(Compositum @  21.6.2008,  18:50 Найти цитируемый пост)
ForeignKeyConstraint foreignkey = new ForeignKeyConstraint(id, father);      

Нужно поменять местами father и id:
Цитата

public ForeignKeyConstraint(
    DataColumn parentColumn,
    DataColumn childColumn
)



--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Compositum
Дата 21.6.2008, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

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



Цитата(Idsa @ 21.6.2008,  15:17)
Нужно поменять местами father и id:
Цитата

public ForeignKeyConstraint(
    DataColumn parentColumn,
    DataColumn childColumn
)


но я же так и делаю - сначала указываю поле первичного ключа, затем внешнего, так что менять не нужно.:
user posted image
поле father дочерней записи должно содержать значение поля id родительской записи. так что все у меня вроде правильно...

Это сообщение отредактировал(а) Compositum - 21.6.2008, 16:30
PM   Вверх
Idsa
Дата 21.6.2008, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 15
Всего: 62



Compositum, насчет порядка аргументов я ошибся.

Судя по всему, ограничения не работают без DataSet. На эту мысль наводит тот факт, что в DataSet есть свойство EnforceConstraints (по умолчанию true), а в таблице же нет средств для включения/выключения ограничений.

Как только добавляешь таблицу в DataSet, ограничения начинают работать. Я добавил следующий код после Вашего:
Код

DataSet dataSet = new DataSet();
      dataSet.Tables.Add(table);

      table.Rows.Add(1, "Name1", "Note1", 1);
      table.Rows.Add(2, "Name2", "Note2", 1);
      table.Rows[0].Delete();

Тогда при удалении первой строки удаляются все строки, в которых она является родителем (Father). Думаю, Вы именно такого поведения добивались?

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

Это сообщение отредактировал(а) Idsa - 21.6.2008, 16:51


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Compositum
Дата 21.6.2008, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

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



Да, я знаю, что если таблицу закинуть в DataSet все начинает работать. Вопрос вызван вот чем: в своей книге Сахил Малик пишет, что ежели программист собирается использовать одну таблицу, то создавать DataSet нет необходимости, поскольку DataTable обладает таким же функционалом и к тому же меньше ресурсов ест. Вот я и пытался реализовать это вне DataSet. 
Я просто не пойму назначений этих полей, если они вне датаСета не работают. 
В датеСете можно сделать и так (та же малина получится):
Код

table = new DataTable("myTable");
            DataColumn id = new DataColumn("ID", typeof(int));
            table.Columns.Add(id);
            table.PrimaryKey = new DataColumn[1] { id };
            id.AutoIncrement = true;
            id.AutoIncrementSeed = 1;
            id.AutoIncrementStep = 1;            
            DataColumn name = new DataColumn("Name", typeof(string));
            table.Columns.Add(name);
            table.Columns["name"].Unique = true;
            DataColumn notes = new DataColumn("Notes", typeof(string));
            table.Columns.Add(notes);
            DataColumn father = new DataColumn("Father", typeof(int));
            father.Unique = false;            
            table.Columns.Add(father);
            //ForeignKeyConstraint foreignkey = new ForeignKeyConstraint(id,father);           
            //foreignkey.DeleteRule = Rule.Cascade;
            //foreignkey.UpdateRule = Rule.Cascade;            
            //table.Constraints.Add(foreignkey);            
            dataset.Tables.Add(table);
            DataRelation relation = new DataRelation("relation", id, father);
            dataset.Relations.Add(relation);

напрашивается вывод - не в каждой ситуации, когда нужно использовать только одну таблицу, подойдет для этого ДатаТабла. Не в каждой...

Это сообщение отредактировал(а) Compositum - 21.6.2008, 17:11
PM   Вверх
Idsa
Дата 21.6.2008, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 15
Всего: 62



Цитата(Compositum @  21.6.2008,  21:08 Найти цитируемый пост)
в своей книге Сахил Малик пишет, что ежели программист собирается использовать одну таблицу, то создавать DataSet нет необходимости, поскольку DataTable обладает таким же функционалом и к тому же меньше ресурсов ест

Да-да. Помню эту фразу из его книги smile

Цитата(Compositum @  21.6.2008,  21:08 Найти цитируемый пост)
напрашивается вывод - не в каждой ситуации, когда нужно использовать только одну таблицу, подойдет для этого ДатаТабла. Не в каждой...

Да, видимо, так и есть. Странно, что я нигде не находил заметок о несостоятельности DataTable при работе с ограничениями. Даже в MSDN ни слова.

Кстати UniqueConstraint работает.
Видимо, ForeignKeyConstraint не работает без DataSet по тому соображению, что в 90% случаев ForeignKeyConstraint связывает 2 разные таблицы. А если есть 2 таблицы, то почему бы их не "упаковать" в DataSet smile Хотя спорно все это.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Magnifico
Дата 22.6.2008, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Должна быть настройка, позволяющая в дочернем поле хранить не только значения родительского поля, но и null

DBNull.Value по умолчанию
можно задать явно  father.AllowDBNull =true;
Код

table.Rows.Add(1, "Name1", "Note1", DBNull.Value);
  table.Rows.Add(2, "Name2", "Note2", 1);
  table.Rows.Add(3, "Name3", "Note3", 2);
  table.Rows.Add(4, "Name4", "Note4", DBNull.Value);
  table.Rows[0].Delete();

интерсно что для реальной таблицы (субд ms sql server) для одной и той же таблицы нельзя задать 
Код

ON DELETE CASCADE 
ON UPDATE CASCADE 


Код

CREATE TABLE [dbo].[Hierarchy]
(
    [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY ,
    [name] [nvarchar](25) ,
    [notes] [nvarchar](25),
    [father] [int] NULL
)

alter TABLE [dbo].[Hierarchy]
add constraint ID_Father Foreign key(father)
references Hierarchy(id)
ON DELETE CASCADE 
ON UPDATE CASCADE 

даст ошибку:
Цитата

Msg 1785, Level 16, State 0, Line 1
Introducing FOREIGN KEY constraint 'ID_Father' on table 'Hierarchy' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

Зацикливание и все такое прочее....


--------------------
Всё  в  порядке   -   спасибо  зарядке  !
PM MAIL   Вверх
Compositum
Дата 22.6.2008, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

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



[QUOTE=Magnifico,22.6.2008,  11:49]
Цитата

интерсно что для реальной таблицы (субд ms sql server) для одной и той же таблицы нельзя задать 
Код

ON DELETE CASCADE 
ON UPDATE CASCADE 

я в курсе. а еще в том же Аксессе Майкрософт таких ограничений не делал - в нем все прекрасно работает. но вопрос был не в этом =)
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

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

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

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


 




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


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

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