Удаление записей из базы данных

73

»» В ДАННОЙ СТАТЬЕ ИСПОЛЬЗУЕТСЯ ИСХОДНЫЙ КОД ДЛЯ ПРИМЕРОВ

Чтобы удалить запись из базы данных с помощью LINQ to SQL, понадобится удалить сущностный объект из Таb1е<Т>, членом которой он является, вызвав метод DeleteOnSubmit объекта Таb1е<Т>. После этого, конечно, необходимо вызвать метод SubmitChanges. Пример приведен ниже.

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

Если вы загрузили упакованную расширенную версию базы данных Northwind, то после запуска этого примера можете просто отсоединить базу данных Northwind, заново извлечь файлы базы данных и снова подключить ее к серверу базы.

// Используйте свою строку подключения
            Northwind db = new Northwind(@"Data Source=MICROSOF-1EA29E\SQLEXPRESS;
                                           AttachDbFilename=C:\Northwind.mdf;
                                           Integrated Security=True");

            Customer cust = (from c in db.Customers
                             where c.CustomerID == "ALFKI"
                             select c).Single<Customer>();

            db.OrderDetails.DeleteAllOnSubmit(
                cust.Orders.SelectMany(o => o.OrderDetails));

            db.Orders.DeleteAllOnSubmit(cust.Orders);
            db.Customers.DeleteOnSubmit(cust);
            db.SubmitChanges();

            Customer cust2 = (from c in db.Customers
                             where c.CustomerID == "ALFKI"
                             select c).SingleOrDefault<Customer>();

            MessageBox.Show(String.Format("Заказчик {0} найден", cust2 != null ? "успешно" : "не"));

Этот пример достаточно прямолинеен, но не лишен интересных аспектов. Во-первых, поскольку таблица Orders содержит внешний ключ, ссылающийся на таблицу Customers, нельзя удалить заказчика без предварительного удаления всех его заказов. И поскольку таблица OrderDetails содержит внешний ключ, ссылающийся на таблицу Orders, нельзя удалить заказ, не удалив его деталей. Таким образом, чтобы удалить заказчика, сначала понадобится удалить детали всех его заказов, затем сами его заказы, и только потом — собственно заказчика.

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

После удаления деталей заказов, самих заказов и их заказчика вызывается метод SubmitChanges. Чтобы доказать, что заказчика больше нет, он запрашивается снова с выводом на экран сообщения.

Удаление присоединенных сущностных объектов

В отличие от автоматической вставки в базу данных присоединенных ассоциированных зависимых сущностных объектов с помощью DataContext, как было показано в примере выше, когда вставлялся их родительский объект, в случае удаления родительского объекта зависимые объекты автоматически не удаляются. Под зависимыми понимаются сущностные объекты, имеющие внешний ключ. Заметьте, сначало пришлось удалять записи OrderDetails перед записями Orders, а записи Orders — перед записью Customers.

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

Удаление отношений

Чтобы удалить отношение между двумя сущностными объектами в LINQ to SQL, ссылке сущностного объекта, указывающей на связанный объект, присваивается значение null. Тем самым удаляется отношение данного сущностного объекта с сущностью этого типа. Однако удаление отношения присваиванием null на самом деле не удаляет самой записи. Помните, что для действительного удаления записи соответствующий ей сущностный объект должен быть удален из соответствующей Таble<Т>. Ниже приведен пример удаления отношения:

// Используйте свою строку подключения
            Northwind db = new Northwind(@"Data Source=MICROSOF-1EA29E\SQLEXPRESS;
                                           AttachDbFilename=C:\Northwind.mdf;
                                           Integrated Security=True");

             // Получить заказ для удаления отношения. 
            Order order = (from o in db.Orders
                           where o.OrderID == 11043 
                           select o) .Single<Order>();
            
            // Сохранить исходного заказчика, чтобы можно было восстановить обратно. 
            Customer с = order.Customer;
            string s = ("Заказы перед удалением отношения:");

            foreach (Order ord in с.Orders)
                s += "\nOrderID = " + ord.OrderID;
            
            // Удалить отношение с заказчиком
            order.Customer = null; 
            db.SubmitChanges();

            s += "\n\nЗаказы после удаления отношения: \n";
            foreach (Order ord in с.Orders)
                s += "\nOrderID = " + ord.OrderID;

            MessageBox.Show(s);

В этом коде запрашивается определенный заказ — тот, у которого OrderID равен 11043. Ссылка на заказчика этого заказа сохраняется для восстановления в конце примера. Далее все заказы этого заказчика сохраняются в переменной s, ссылке на заказчика для извлеченного заказа присваивается значение null, после чего вызывается метод SubmitChanges для сохранения изменений в базе данных. Затем отображаются все заказы данного заказчика, и на этот раз в списке заказ с OrderID, равным 11043, отсутствует. Вывод кода показан ниже:

Удаление отношения между двумя сущностными объектами

Как видите, после удаления отношения между заказчиком и заказом с OrderID, равным 11043, он исчез из коллекции заказов данного заказчика.

Пройди тесты
Лучший чат для C# программистов