Ответ 1
В Entity Framework 6 действие удаления Remove
. Вот пример
Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.Remove(customer);
context.SaveChanges();
Мне кажется, что мне нужно получить объект, прежде чем я удаляю его с помощью сущности, как показано ниже
var customer = context.Customers.First(c => c.Id == 1);
context.DeleteObject(customer);
context.Savechanges();
Поэтому мне нужно дважды поразить базу данных. Есть ли более простой способ?
В Entity Framework 6 действие удаления Remove
. Вот пример
Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.Remove(customer);
context.SaveChanges();
То же, что и @Nix с небольшим изменением, которое нужно строго набирать:
Если вы не хотите запрашивать его, просто создайте объект, а затем удалите его.
Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.DeleteObject(customer);
context.SaveChanges();
Аналогичный вопрос здесь.
В 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();
Он также полезен для массовых удалений.
Если вы не хотите запрашивать его, просто создайте объект, а затем удалите его.
Customer customer = new Customer() { Id = 1 } ;
context.AttachTo("Customers", customer);
context.DeleteObject(customer);
context.Savechanges();
Я использую следующий код в одном из моих проектов:
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.]
Сырой запрос 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.
}
}
Если вы используете EF 1.0, это самый сжатый способ сделать это. Могут быть и другие способы, но у них больше проблем, чем их ИМХО.
Ответ 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();