Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新或删除EntityFramework中的多个实体的建议做法是什么?_C#_.net_Sql_Entity Framework - Fatal编程技术网

C# 更新或删除EntityFramework中的多个实体的建议做法是什么?

C# 更新或删除EntityFramework中的多个实体的建议做法是什么?,c#,.net,sql,entity-framework,C#,.net,Sql,Entity Framework,在SQL中,有时可能会编写如下内容 DELETE FROM table WHERE column IS NULL foreach (var entity in db.Table.Where(row => row.Column == null)) db.Table.Remove(entity); // or entity.Column2 = value; db.SaveChanges(); 或 或可能应用于多行的任何其他标准 据我所知,EntityFramework所能做的最

在SQL中,有时可能会编写如下内容

DELETE FROM table WHERE column IS NULL
foreach (var entity in db.Table.Where(row => row.Column == null))
    db.Table.Remove(entity);   // or entity.Column2 = value;
db.SaveChanges();

或可能应用于多行的任何其他标准

据我所知,EntityFramework所能做的最好的事情是

DELETE FROM table WHERE column IS NULL
foreach (var entity in db.Table.Where(row => row.Column == null))
    db.Table.Remove(entity);   // or entity.Column2 = value;
db.SaveChanges();
当然,这将检索所有实体,然后对每个实体运行单独的删除查询。当然,如果有许多实体满足这一标准,那么速度肯定要慢得多


因此,长话短说,EntityFramework是否支持在一个查询中更新或删除多个实体?

EF不支持批量更新或删除,但您可以简单地执行以下操作:

db.Database.ExecuteSqlCommand("DELETE FROM ...", someParameter);
编辑:

真正想坚持使用LINQ查询的人有时会使用变通方法,首先从LINQ查询创建select SQL查询:

string query = db.Table.Where(row => row.Column == null).ToString();
然后从中找到第一个出现的
,并用
DELETE
替换查询的开头,并用
ExecuteSqlCommand
执行结果。这种方法的问题是,它只在基本场景中有效。它不适用于实体拆分或某些继承映射,在这些映射中,每个实体需要删除两个或多个记录。

请查看。此项目允许使用lambda表达式进行集合操作。文件样本:

this.Container.Devices.Delete(o => o.Id == 1);

this.Container.Devices.Update(
     o => new Device() { 
        LastOrderRequest = DateTime.Now, 
        Description = o.Description + "teste"
     }, 
     o => o.Id == 1);
通过挖掘,您可以看到@Ladislav Mrnka第二种方法是如何自动化的,同时添加了设置操作:

    public override string GetDmlCommand()
    {
        //Recover Table Name

        StringBuilder updateCommand = new StringBuilder();
        updateCommand.Append("UPDATE ");
        updateCommand.Append(MetadataAccessor.GetTableNameByEdmType(
                                  typeof(T).Name));
        updateCommand.Append(" ");
        updateCommand.Append(setParser.ParseExpression());
        updateCommand.Append(whereParser.ParseExpression());

        return updateCommand.ToString();
    }
三年后编辑


看看这个伟大的答案:

实体框架扩展库有助于做到这一点

删除

//delete all users where FirstName matches
context.Users.Delete(u => u.FirstName == "firstname");
更新

//update all tasks with status of 1 to status of 2
context.Tasks.Update(
    t => t.StatusId == 1, 
    t2 => new Task {StatusId = 2});

//example of using an IQueryable as the filter for the update
var users = context.Users.Where(u => u.FirstName == "firstname");
context.Users.Update(users, u => new User {FirstName = "newfirstname"});

呸。。。那太令人失望了。是否有一些很好的方法来抽象表名和字段名之类的细节?或者将LINQ“Where”子句(它返回的
IQueryable
)转换为可运行SQL?是的,正如romkyns所说的令人失望。。。我想知道他们认为不值得实现的具体原因是什么,因为我很难想象任何DB驱动的web应用程序不需要偶尔的批量更新/删除操作。-如果你知道romkyns问题的答案,那就太酷了@Timwi:但它仍然受到支持——即使使用EF,执行原始SQL仍然是有效的技术。您只需在您的上下文中创建一个内部执行SQL的方法,您的上层就可以使用该方法。创建delete/update命令是一种更可靠的方法,因为它转换表达式而不是解析字符串查询,但通过查看源代码,似乎也没有涵盖复杂的映射。@LadislavMrnka,这只是一段代码来说明答案。请随意查看。这个项目似乎不再维护了。