2013-03-18 9 views
10

Po prostu mam bardzo prostą sytuację, w której wszystko, czego potrzebuję, to usunięcie rekordu za pomocą Linq2Entities. Próbowałem przeprowadzić pewne badania i nadal nie potrafię znaleźć właściwej drogi.Właściwy sposób na usunięcie rekordu w LINQ do encji

Oto mój prosty kod:

[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(); 
    } 
} 

mogę usunąć konkretny rekord, jeśli na przykład przypisać y.EmployeeName == „Harold Javier” metody kasowania powyżej, ale kiedy przypisać y .EmployeeId == z.EmployeeId na powyższy kod, usunięcie nie działa. (Uwaga: EmployeeId jest kluczem podstawowym tabeli Employee)

+3

Na czym polega problem z kodem? Jakieś błędy?opublikuj je, jeśli tak. –

+0

Możemy skompilować kod i wydaje się to w porządku. Ale gdy używamy go z ObjectDataSource (ASP.NET WebForm), przycisk Usuń nie działa. –

+0

Wypróbuj 'ctx.Employees.DeleteOnSubmit (x)' zamiast 'ctx.DeleteObject (x)' – MarcinJuraszek

Odpowiedz

3

Postanowiłem odpowiedzieć na własne pytanie.

Moja funkcja kasowania pracował kiedy robiłam następujące:

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

wiem, że może być lepszym rozwiązaniem niż to, ale to działa na mnie po raz średniej.

5

najpierw musisz sprawdzić, czy rekord istnieje, zanim go usuniesz;

[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(); 
      } 
     } 
    } 

Zawsze sprawdzaj wartości zerowe, zanim coś usuniesz. Ponieważ użytkownik może zmienić ID (w querystringu) i wypróbować różne kombinacje.

+1

Dzięki, DonNet Dreamer. Ale wciąż sprawdzanie wartości zerowych nie rozwiązuje naszego problemu. –

+0

Zawsze używałam funkcji Delete jako metody POST ('[HttpPost]'), a nie get, co eliminuje potrzebę zabezpieczenia kwerendy. Kontrola zerowa to zawsze dobra praktyka, ale nie jest ona odpowiednia dla pytania OP, a także nie jest najlepszym sposobem zabezpieczenia wniosku. – Flater

1

Jest tak prawdopodobnie dlatego, że kontekst jest inny w przypadku każdego żądania (var ctx = new MyEntity()). Spróbuj użyć tego

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

i usuwać jest jak

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(); 
} 
10

myślę, że to jest lepsza opcja kasowania

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

przy moim boku DeleteObject nie działa więc używam Remove

1

Powyższa odpowiedź może być nieaktualna ... Metoda DeleteObject nie wydaje się być jest w aktualnej wersji ENtity Framework. Musiałem użyć metody Remove.

2

@Harold, wiem, że ten post jest dość stary, ale uważam, że ważne jest, aby zająć się pierwotnym pytaniem i odpowiedzią. Twoje rozwiązanie mogło zadziałać w twojej sytuacji, ale jest kilka problemów.

Najpierw Twój oryginalny kod wybrał rekord do usunięcia na podstawie przekazanego parametru. Twoje rozwiązanie polega na usunięciu rekordu za pomocą największego EmployeeId. To może być to, czego chcesz, ale mało prawdopodobne. Drugą kwestią jest to, że do usunięcia są wymagane dwa dostępy do baz danych. Pierwszym z nich jest pobranie obiektu do usunięcia drugiego, aby faktycznie wykonać usuwanie.

Poniższy fragment kodu eliminuje konieczność czytania i usuwa pracownika "z". To powinno dać pożądany wynik i osiągnąć znacznie lepsze wyniki.

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(); 
    } 
} 
Powiązane problemy