C# 在 LINQ to Entities 中删除记录的正确方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15469684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:56:19  来源:igfitidea点击:

Proper way to delete record in LINQ to Entities

c#linqentity-frameworklinq-to-entities

提问by Harold Javier

I just have a very simple situation where all I need is to delete record using Linq2Entities. I tried to do some research and still can't figure out the right way to do it.

我只是有一个非常简单的情况,我需要的只是使用 Linq2Entities 删除记录。我试图做一些研究,但仍然无法找到正确的方法。

Here's my simple code:

这是我的简单代码:

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

I can delete a particular record if for example I assign y.EmployeeName == "Harold Javier"to the Delete method above, but when I assign y.EmployeeId == z.EmployeeIdto the above code, the delete doesn't work. (Note: EmployeeId is the primary key of the Employee table)

例如,如果我将y.EmployeeName == "Harold Javier"分配给上面的 Delete 方法,我可以删除特定记录,但是当我将y.EmployeeId == z.EmployeeId分配给上述代码时,删除不起作用。(注:EmployeeId是Employee表的主键)

采纳答案by Harold Javier

I decided to answer my own question.

我决定回答我自己的问题。

My delete function worked when I did the following:

当我执行以下操作时,我的删除功能起作用了:

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

I know there could be a better approach than this, but it works for me for the mean time.

我知道可能有比这更好的方法,但它同时对我有用。

回答by Idrees Khan

you first need to verify that if a record exists before you actually delete it;

在实际删除记录之前,您首先需要验证记录是否存在;

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

Always check for nulls, before you delete something. Because a user may change the Id (at querystring) and try different combinations.

在删除某些内容之前,请始终检查空值。因为用户可能会更改 Id(在查询字符串中)并尝试不同的组合。

回答by Janne Matikainen

This is probably because the context is different on each request (var ctx = new MyEntity()). Try using this

这可能是因为每个请求的上下文都不同(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;
        }
    }
}

And delete is like

和删除就像

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

回答by Sanket Gandhi

I think this is better option of delete

我认为这是删除的更好选择

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

at my side DeleteObjectis not working so i use Remove

在我身边DeleteObject不工作所以我使用Remove

回答by Scooter

The above answer may be outdated... The DeleteObject method does not seem to exist in the current version of ENtity Framework. I had to use the Remove method.

上面的答案可能已经过时了......当前版本的ENtity Framework中似乎不存在DeleteObject方法。我不得不使用 Remove 方法。

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

回答by Jim Reineri

@Harold, I know this post is quite old, but I feel it is important to address your original question and answer. Your solution may have worked in your situation, but there are a couple of problems.

@Harold,我知道这篇文章已经很老了,但我觉得解决您最初的问题和答案很重要。您的解决方案可能适用于您的情况,但存在一些问题。

First, your original code was selecting the record to delete based on a passed in parameter. Your solution is deleting the record with the largest EmployeeId. That might be what you wish, but not likely. The second issue is that two database accesses are required to accomplish the delete. The first is get the entity to delete the second to actually perform the delete.

首先,您的原始代码是根据传入的参数选择要删除的记录。您的解决方案是删除具有最大 EmployeeId 的记录。这可能是你想要的,但不太可能。第二个问题是需要两次数据库访问才能完成删除。第一个是获取要删除的实体,第二个是实际执行删除。

The following code snippet will eliminate the need to to the read and will delete employee "z". This should yield the desired result and perform much better.

以下代码片段将消除读取的需要,并将删除员工“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();  
    }
}

回答by Hymanson Rosado

The following worked for me:

以下对我有用:

MyList.RemoveAll(x => x.MyField == 0);