Как удалить объект по идентификатору с сущностью

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

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

context.DeleteObject(customer);

context.Savechanges();

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

Ответ 1

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

Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.Remove(customer);
context.SaveChanges();

Ответ 2

То же, что и @Nix с небольшим изменением, которое нужно строго набирать:

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

                Customer customer = new Customer () { Id = id };
                context.Customers.Attach(customer);
                context.Customers.DeleteObject(customer);
                context.SaveChanges();

Ответ 3

Аналогичный вопрос здесь.

В 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();

Он также полезен для массовых удалений.

Ответ 4

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

Customer customer  = new Customer() {  Id = 1   } ; 
context.AttachTo("Customers", customer);
context.DeleteObject(customer);
context.Savechanges();

Ответ 5

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

    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;
            }
        }
    }

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

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

Ответ 6

Сырой запрос 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.
   }
}

Ответ 7

Если вы используете EF 1.0, это самый сжатый способ сделать это. Могут быть и другие способы, но у них больше проблем, чем их ИМХО.

Ответ 8

Ответ 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();