web-dev-qa-db-ja.com

LINQ to Entitiesのレコードを削除する適切な方法

必要なのは、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 == "Harold Javier"を上記のDeleteメソッドに割り当てた場合、特定のレコードを削除できますが、y.EmployeeId == z.EmployeeId上記のコードでは、削除は機能しません。 (注:EmployeeIdはEmployeeテーブルのプライマリキーです)

13
Harold Javier

私は自分の質問に答えることにしました。

削除機能は、次のことを行ったときに機能しました。

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

私はこれよりも良いアプローチがあるかもしれないことを知っていますが、それは当分の間はうまくいきます。

4
Harold Javier

これは削除のより良いオプションだと思います

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を使用します

13
Sanket Gandhi

実際に削除する前に、レコードが存在するかどうかを最初に確認する必要があります。

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

何かを削除する前に、常にヌルをチェックしてください。ユーザーは(クエリ文字列で)Idを変更し、さまざまな組み合わせを試すことができるためです。

5
DotNet Dreamer

上記の答えは時代遅れかもしれません... DeleteObjectメソッドはENtity Frameworkの現在のバージョンには存在しないようです。 Removeメソッドを使用する必要がありました。

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

@Harold、この投稿はかなり古いものですが、元の質問と回答に対処することが重要だと思います。あなたのソリューションはあなたの状況でうまく機能したかもしれませんが、いくつかの問題があります。

まず、元のコードは、渡されたパラメーターに基づいて削除するレコードを選択していました。ソリューションは、最大のEmployeeIdを持つレコードを削除しています。それはあなたが望むものかもしれませんが、そうではありません。 2番目の問題は、削除を実行するために2つのデータベースアクセスが必要なことです。 1つ目は、エンティティを取得して2つ目を削除し、実際に削除を実行します。

次のコードスニペットは、読み取りの必要性を排除し、従業員「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();  
    }
}
3
Jim Reineri

次は私のために働いた:

MyList.RemoveAll(x => x.MyField == 0);
1
Jackson Rosado

これはおそらく、コンテキストがリクエストごとに異なるためです(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();
}
1