Как удалить объект по идентификатору с помощью Entity Framework - PullRequest
85 голосов
/ 18 марта 2010

Мне кажется, что я должен получить объект, прежде чем удалить его с помощью структуры сущностей, как показано ниже

var customer = context.Customers.First(c => c.Id == 1);

context.DeleteObject(customer);

context.Savechanges();

Так что мне нужно дважды нажать на базу данных. Есть ли более простой способ?

Ответы [ 7 ]

72 голосов
/ 20 января 2015

В Entity Framework 6 действие удаления - Remove.Вот пример

Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.Remove(customer);
context.SaveChanges();
52 голосов
/ 09 декабря 2012

То же, что и @Nix с небольшим изменением для строгой типизации:

Если вы не хотите запрашивать его, просто создайте объект, а затем удалите его.

                Customer customer = new Customer () { Id = id };
                context.Customers.Attach(customer);
                context.Customers.DeleteObject(customer);
                context.SaveChanges();
24 голосов
/ 23 июля 2013

Подобный вопрос здесь .

В Entity Framework есть EntityFramework-Plus (библиотека расширений).
Доступно на NuGet. Тогда вы можете написать что-то вроде:

// DELETE all users which has been inactive for 2 years
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2))
     .Delete();

Это также полезно для массового удаления.

22 голосов
/ 25 марта 2010

Если вы не хотите запрашивать его, просто создайте сущность, а затем удалите ее.

Customer customer  = new Customer() {  Id = 1   } ; 
context.AttachTo("Customers", customer);
context.DeleteObject(customer);
context.Savechanges();
5 голосов
/ 24 июня 2017

Я использую следующий код в одном из моих проектов:

    using (var _context = new DBContext(new DbContextOptions<DBContext>()))
    {
        try
        {
            _context.MyItems.Remove(new MyItem() { MyItemId = id });
            await _context.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            if (!_context.MyItems.Any(i => i.MyItemId == id))
            {
                return NotFound();
            }
            else
            {
                throw ex;
            }
        }
    }

Таким образом, он будет запрашивать базу данных дважды, только если возникает исключение при попытке удалить элемент с указанным идентификатором. Затем, если элемент не найден, он возвращает значимое сообщение; в противном случае он просто отбрасывает исключение (вы можете обработать его более подходящим образом для вашего случая, используя разные блоки catch для разных типов исключений, добавив больше пользовательских проверок, используя блоки if и т.

[Я использую этот код в проекте MVC .Net Core / .Net Core с Entity Framework Core.]

2 голосов
/ 28 февраля 2014

Необработанный SQL-запрос - это самый быстрый способ, который я предполагаю

public void DeleteCustomer(int id)
{
   using (var context = new Context())
   {
      const string query = "DELETE FROM [dbo].[Customers] WHERE [id]={0}";
      var rows = context.Database.ExecuteSqlCommand(query,id);
      // rows >= 1 - count of deleted rows,
      // rows = 0 - nothing to delete.
   }
}
1 голос
/ 25 апреля 2019

Ответ dwkd в основном работал для меня в ядре Entity Framework, кроме случаев, когда я видел это исключение:

InvalidOperationException: экземпляр типа сущности «Клиент» не может быть отслеженным, потому что другой экземпляр с тем же значением ключа для {'Id'} уже отслеживается. При присоединении существующих объектов убедитесь, что что только один экземпляр сущности с данным значением ключа присоединен. Рассмотрите возможность использования DbContextOptionsBuilder.EnableSensitiveDataLogging для увидеть конфликтующие ключевые значения.

Чтобы избежать исключения, я обновил код:

Customer customer = context.Customers.Local.First(c => c.Id == id);
if (customer == null) {
    customer = new Customer () { Id = id };
    context.Customers.Attach(customer);
}
context.Customers.Remove(customer);
context.SaveChanges();
...