Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > ограничения в ADO.NET


Автор: Compositum 23.5.2008, 22:50
Не пойму, почему не происходит исключение, когда полю внешнего ключа присваивается не существующее значение первичного. Так же расстроен отсутствием ограничений Check в ADO.NET
Код с комментариями:
Код

public class EntryPoint
    {
        public static void Main()
        {
            //Создаю таблицу, структура которой содержит некую иерархию чего-либо:
            //1.Сначала формирую поля таблицы
            DataColumn id = new DataColumn("id", typeof(int));
            DataColumn name = new DataColumn("name", typeof(string));
            DataColumn notes = new DataColumn("notes", typeof(string));
            DataColumn father = new DataColumn("father", typeof(int));
            //2. теперь собираю их в массив и закидываю в таблицу
            DataColumn[] items = new DataColumn[] { id, name, notes, father };
            DataTable tree = new DataTable("tree");
            tree.Columns.AddRange(items);
            //3. Настраиваю созданную таблицу: формирую для нее первичный и внешний ключи,
            //а так же необходимые ограничения
            tree.PrimaryKey = new DataColumn[] { tree.Columns["id"] };
            tree.Columns["id"].AutoIncrement = true;
            tree.Columns["id"].AutoIncrementSeed = 1;
            tree.Columns["id"].AutoIncrementStep = 1;
            tree.Columns["id"].AllowDBNull = false;
            tree.Columns["id"].ReadOnly = true;            
            UniqueConstraint constr = new UniqueConstraint("unique",new DataColumn[]{
                            tree.Columns["name"],tree.Columns["father"]},false);
            ForeignKeyConstraint foreign = new ForeignKeyConstraint(tree.Columns["id"],
                tree.Columns["father"]);
            foreign.DeleteRule = Rule.Cascade;
            foreign.UpdateRule = Rule.Cascade;             
            tree.Constraints.Add(constr);  
            tree.Constraints.Add(foreign);
          
            //***Теперь тестирую созданную мною таблицу: создаю записи
            //и добавляю их в таблицу
            DataRow row1 = tree.NewRow();
            row1["name"] = "telephone";
            row1["notes"] = "samsung or sony";
            //Сейчас я создам запись со значением в поле father, не согласующимся с полем первичного
            //ключа - т.о. должно быть возбуждено исключение!
            DataRow row2 = tree.NewRow();
            row2["name"] = "NOTEBOOK";
            row2["notes"] = "SONY VAIO";    
            row2["father"] = 992; // здесь указываю не допустимое значение. 
            DataRow row3 = tree.NewRow();
            row3["name"] = "I love C# 3.0";
            row3["notes"] = "coder";
            row3["father"] = 3;//здесь тоже казус... нужно проверять, чтобы father !=id. т.е. чтобы
            // не получалось, что запись подчиняется сама себе, но ограничение CHECK в ADO.NET, 
            //как я понял из Сахила Малика - нет. Жаль конечно, хотя это можно сделать и программно.
            //Так же пытаюсь спровоцировать ошибку и при добавлении этой записи:
            DataRow row4 = tree.NewRow();// 
            row4["name"] = "I love C# 3.0";
            row4["father"] = 3;// исключение происходит - я получаю сообщение в окне консоли и
            //запись не добавляется в таблицу - как и требуется.

            //формирую из созданных мною строк массив
            DataRow[] rows = new DataRow[] { row1, row2, row3, row4 };
            //добавляю массив строк в таблицу через свою функцию           
            AddRow(tree, rows);   //при добавлении строк в таблу должен получить сообщение об
            // исключении - но не получаю         
                        
            for (int i = 0; i < tree.Columns.Count; i++)
            {
                Console.Write(tree.Columns[i].ColumnName + "\t");
            }
            Console.WriteLine("\n______________________________________________");
            foreach (DataRow row in tree.Rows)
            {
                for (int i = 0; i < row.Table.Columns.Count; i++)
                {
                    Console.Write(row[i].ToString() + "\t");
                }                
                Console.WriteLine();                
            }
            Console.WriteLine("______________________________________________");
            Console.WriteLine("Всего записей в таблице: {0}", tree.Rows.Count);
            Console.Read();
        } 
        //Функция, позволяющая добавлять в таб
        private static void AddRow(DataTable table, DataRow[] rows)
        {
            foreach (DataRow item in rows)
            {
                try
                {
                    table.Rows.Add(item);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Ошибка: {0}", e.Message);
                }
            }
        }
    }

Результат:

user posted image

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)