Правильный способ удаления записи в LINQ для объектов

У меня просто очень простая ситуация, когда мне нужно только удалить запись с помощью Linq2Entities. Я попытался сделать некоторые исследования и до сих пор не могу понять, как правильно это сделать.

Вот мой простой код:

[DataObjectMethod(DataObjectMethodType.Delete)]
public void DeleteEmployee(Employee z)
{
    using (var ctx = new MyEntity())
    {
        var x = (from y in ctx.Employees
                 where  y.EmployeeId == z.EmployeeId
                 select y).FirstOrDefault();
         ctx.DeleteObject(x);
         ctx.SaveChanges();
    }
 }

[DataObjectMethod(DataObjectMethodType.Select)]
public List<Employee> GetAllEmployee()
{
    using (var ctx = new MyEntity())
    {
        var x = from y in ctx.Employees
                select y;
        return x.ToList();
    }
}

Я могу удалить конкретную запись, если, например, я назначил y.EmployeeName == "Гарольд Хавьер" методу Delete выше, но когда я назначаю y.EmployeeId == z. EmployeeId к вышеуказанному коду, удаление не работает. (Примечание: EmployeeId является основным ключом таблицы Employee)

Ответ 1

Я решил ответить на свой вопрос.

Моя функция удаления работала, когда я сделал следующее:

using (var ctx = new MyEntity())
    {
        var x = (from y in ctx.Employees
             orderby  y.EmployeeId descending
             select y).FirstOrDefault();
        ctx.Employees.DeleteObject(x);
        ctx.SaveChanges();
    }

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

Ответ 2

Я думаю, что это лучший вариант удаления

using (var ctx = new MyEntity())
    {
        var x = (from y in ctx.Employees
             orderby  y.EmployeeId descending
             select y).FirstOrDefault();
        ctx.Employees.Remove(x);
        ctx.SaveChanges();
    }

на моей стороне DeleteObject не работает, поэтому я использую Remove

Ответ 3

сначала вам нужно проверить, существует ли запись до фактического ее удаления;

[DataObjectMethod(DataObjectMethodType.Delete)]

    public void DeleteEmployee(Employee z)
    {
        using (var ctx = new MyEntity())
        {
            var x = (from y in ctx.Employees
                     where  y.EmployeeId == z.EmployeeId
                     select y).FirstOrDefault();
             if(x!=null)
             {
             ctx.Employees.DeleteObject(x);
             ctx.SaveChanges();
             }
        }
     }

Всегда проверяйте нули, прежде чем что-то удалять. Поскольку пользователь может изменить идентификатор (при запросе) и попробовать различные комбинации.

Ответ 4

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

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

Следующий фрагмент кода устранит необходимость чтения и удалит сотрудника "z". Это должно дать желаемый результат и выполнить намного лучше.

public void DeleteEmployeeId(Employee z)
{
    using (var ctx = new MyEntityContext())  
    {  
        var x = new Employee{ EmployeeId = z.EmployeeId };
        ctx.Entry(x).State = EntityState.Deleted;  
        ctx.SaveChanges();  
    }
}

Ответ 5

Вероятно, это связано с тем, что для каждого запроса контекст отличается (var ctx = new MyEntity()). Попробуйте использовать

public static class ObjectContextPerHttpRequest
{
    public static TestCasesModelContainer Context
    {
        get
        {
            string objectContextKey = HttpContext.Current.GetHashCode().ToString("ObjectContextPerHttpRequest");

            if (!HttpContext.Current.Items.Contains(objectContextKey))
            {
                HttpContext.Current.Items.Add(objectContextKey, new TestCasesModelContainer());
            }

            return HttpContext.Current.Items[objectContextKey] as TestCasesModelContainer;
        }
    }
}

И удаление похоже на

public static void Delete(Testcase tc)
{
    var db = ObjectContextPerHttpRequest.Context;

    db.DeleteObject((from p in db.TestcaseSet
                     where p.Id == tc.Id
                     select p).Single());
    db.SaveChanges();
}

Ответ 6

Вышеприведенный ответ может быть устаревшим... Метод DeleteObject, похоже, не существует в текущей версии ENtity Framework. Мне пришлось использовать метод Remove.

var delobj = db.mytable.Where(p => p.ServiceLocation == serviceLocationID).SingleOrDefault();
db.myTable.Remove(delobj);