删除.NET Core 6中的查找表记录未能正常工作。

huangapple go评论62阅读模式
英文:

Deleting records from look up table not working in .NET Core 6

问题

我最近升级了我的项目到.NET Core 6,现在无法从我的查找表中删除记录。我有一个名为Risk的对象,它包含一个Users的集合。从风险对象中删除用户不再起作用。有没有什么想法我做错了?

我的查找表名为RiskItemUser,它有两列,RiskItemIdUserId

代码:

var postSavedRisk = _riskService.Queryable().Include(c => c.AssignedTo).Where(w => w.Id == riskitem.Id).FirstOrDefault();

List<User> usersToRemove = postSavedRisk.AssignedTo.Where(c => userNamesToRemove.Contains(c.UserName)).ToList();

using (var db = new ApplicationDbContext())
{
    var postSavedAssginedTo = db.RiskItemUser
                                .Where(w => w.RiskItemId == riskitem.Id)
                                .ToList();

    foreach (var userToRemove in usersToRemove)
    {
        foreach (var riskAssignedTo in postSavedAssginedTo)
        {
            if (userToRemove.Id == riskAssignedTo.UserId)
                db.RiskItemUser.Remove(riskAssignedTo);

            await db.SaveChangesAsync().ConfigureAwait(false);
        }
    }
}
英文:

I recently upgraded my project to .NET Core 6 and now removing records from my look up tables is not working. I have a Risk object that has a collection of Users. Removing users from the risk object no longer works. Any ideas what I'm doing wrong?

My lookup table is called RiskItemUser, and it has two columns, RiskItemId and UserId.

Code:

 var postSavedRisk = _riskService.Queryable().Include(c =&gt; c.AssignedTo).Where(w =&gt; w.Id == riskitem.Id).FirstOrDefault();
       
 List&lt;User&gt; usersToRemove = postSavedRisk.AssignedTo.Where(c =&gt; userNamesToRemove.Contains(c.UserName)).ToList();
          
using (var db = new ApplicationDbContext())
{
    var postSavedAssginedTo = db.RiskItemUser
                                .Where(w =&gt; w.RiskItemId == riskitem.Id)
                                .ToList();

    foreach (var userToRemove in usersToRemove)
    {
        foreach (var riskAssignedTo in postSavedAssginedTo)
        {
            if(userToRemove.Id == riskAssignedTo.UserId)
                db.RiskItemUser.Remove(riskAssignedTo);

            await db.SaveChangesAsync().ConfigureAwait(false);
        }
    }
}

答案1

得分: 2

以下是翻译好的部分:

The code, as you show it, looks like it should work, although some parts are hidden. Therefore, it's hard to tell how to make it work. But there's room for simplification, which should result in working code.

你展示的代码看起来应该可以工作,尽管有些部分是隐藏的。因此,很难确定如何使它工作。但有简化的空间,这应该可以产生有效的代码。

You want to remove users whose names are specified by userNamesToRemove from a risk that's specified by riskitem.Id. Assuming that there's a navigation property RiskItemUser.User, removing these data could be done by essentially one line of code:

你想从由riskitem.Id指定的风险中删除由userNamesToRemove指定的用户名的用户。假设有一个导航属性RiskItemUser.User,删除这些数据可以通过基本上一行代码来完成:

db.RiskItemUser.RemoveRange(
    db.RiskItemUser.Where(ru =&gt; ru.RiskItemId == riskitem.Id 
        &amp;&amp; userNamesToRemove.Contains(ru.User.Name)));

await db.SaveChangesAsync().ConfigureAwait(false);

你标记了EFC 6,但截止到EFC 7.0,已经支持批量删除(和更新)函数,允许单语句删除多个数据库记录:

db.RiskItemUser
    .Where(db.RiskItemUser.Where(ru =&gt; ru.RiskItemId == riskitem.Id 
        &amp;&amp; userNamesToRemove.Contains(ru.User.Name)))
    .ExecuteDelete();

这将执行一条删除语句,而以前的方法将对每一行执行一条语句。

请注意,这种批量方法类似于执行原始SQL。它与EF的更改跟踪器没有通信,EF不能协调语句的正确顺序。我认为一般建议是不要将这些批量方法与常规的SaveChanges调用混合使用。

英文:

The code, as you show it, looks like it should work, although some parts are hidden. Therefore, it's hard to tell how to make it work. But there's room for simplification, which should result in working code.

You want to remove users whose names are specified by userNamesToRemove from a risk that's specified by riskitem.Id. Assuming that there's a navigation property RiskItemUser.User, removing these data could be done by essentially one line of code:

db.RiskItemUser.RemoveRange(
    db.RiskItemUser.Where(ru =&gt; ru.RiskItemId == riskitem.Id 
        &amp;&amp; userNamesToRemove.Contains(ru.User.Name)));

await db.SaveChangesAsync().ConfigureAwait(false);

You tagged EFC 6, but as of EFC 7.0, there's support for bulk delete (and update) functions, allowing for single-statement deletion of multiple database records:

db.RiskItemUser
    .Where(db.RiskItemUser.Where(ru =&gt; ru.RiskItemId == riskitem.Id 
        &amp;&amp; userNamesToRemove.Contains(ru.User.Name)))
    .ExecuteDelete();

This will execute one delete statement, whereas the previous method will execute one statement per row.

Note that this bulk method is like executing raw SQL. There's no communication with EF's change tracker and EF can't coordinate the correct order of statements. I think the general advice should be to not mix these bulk methods with regular SaveChanges calls.

huangapple
  • 本文由 发表于 2023年2月8日 11:13:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75381064.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定