【问题标题】:API adds several records instead of the oneAPI 添加了几条记录而不是一条
【发布时间】:2023-04-03 14:22:01
【问题描述】:

我刚刚从 net core 2.2 迁移到 mvc net core 3.0。现在,每次当我尝试向数据库添加新记录时,应用程序都会在数据库中创建 9 个相同记录的副本。我的 Db 中有很多表,而且每张表都会发生这种情况。当我使用 net core 2.2 时,一切正常。

我正在使用此代码向数据库添加新记录:

数据库上下文文件:

public virtual async Task<T> AddAsync(T t)
{
    Context.Set<T>().Add(t);
    await Context.SaveChangesAsync();
    return t;
}

从控制器调用的存储库调用此函数:

public async Task<IActionResult> AddItem(Item item)
{
    .....
}

从客户端的 jquery ajax 调用控制器,并且在单击添加按钮时向控制器发送请求。

$(document).on("click", "#addItem",
    function (e) {
        e.preventDefault();
        e.stopPropagation();
        var route="...";
        var formId="...";
     var form = $(formId);
        form.validate();
        if (!form.valid()) return;
        addCompany(route,formId);
});

function addCompany(route, formId) {
  
alert("start");

    var form = $(formId);
        var formData = form.serialize();
        
        $.ajax({
            async: true,
            url: route,
            type: "POST",
            cache: false,
            data: formData,
          
            success: function (result) {
                alert("sucess");
               

            },
            error: function (xhr) {
                alert("error");
               
            }
        });
};

我可以在屏幕上看到 9 次“开始”警报。过了一会儿,我可以看到 9 次“成功”警报。

当我尝试在调试器中跟踪代码时,我可以看到从一个函数到另一个函数的执行过程是混乱的——在一个函数中多次执行一行代码,之后在另一个函数中执行多次。之后,它返回到第一个函数的另一行,一切重复 5-10 次。

最奇怪的是,这9条记录通常都保存在MS server Db中。它们具有所有字段和键。但是当我在屏幕上打开它们中的任何一个时,它显示所有字段都是空的。但是使用相同的应用程序,我仍然可以正常打开并在屏幕上查看在迁移到 Core 3.0 之前保存的记录

【问题讨论】:

  • 不完整。 9个副本是否具有相同的ID? SaveChanges 的任何覆盖?你怎么称呼这个方法?当你在这里设置断点时,它的命中频率是多少?等
  • “从一个函数到另一个函数的执行混乱”意味着您在多个线程(请求)上运行。因此,请向我们展示您如何/何时调用 AddCompany()。

标签: c# jquery ajax entity-framework .net-core


【解决方案1】:

我在您给出的代码中看不到任何理由,为什么它会多次保存记录。

我可以看到执行从一个函数到另一个函数是混乱的

如果有多个线程在运行,这是正常的。调试时,Visual Studio 的工具栏中有一个“线程”下拉菜单。当您看到它“跳转”到代码的另一部分时,请注意在该下拉列表中选择的线程号是不同的。

但这可能表明正在处理多个请求(即您实际上发送了 9 个请求)。您应该能够在客户端验证这一点(无论客户端是什么),或者您可以删除所有断点,并在控制器操作中仅设置一个:

public async Task<IActionResult> AddCompany(Company item)
{
    //set breakpoint here
    var newcompany = await _companiesRepository.AddCompany(item);
}

当该断点被命中时,按 F5。只需计算该断点被命中的次数。

顺便说一句,我不太明白你在这里做什么:

public async Task<Company> AddCompany(Company item)
{
    var savedItem = await base.AddAsync(item);

    var exist = Context.Companies.Find(savedItem.Id);
    if (exist == null) return exist;

    return savedItem;
}

如果项目被正确保存,那么savedItem.Id 将有一个值(假设这是主键,由数据库生成?)。那么为什么你需要搜索它以查看它是否存在呢?毕竟如果没有保存成功,就会抛出异常。

那如果是null,你为什么要返回exist?请注意,出于同样的原因,这永远不会发生(如果不保存,则会引发异常,您将永远无法访问该行代码)。

我觉得您可以将其简化为:

public Task<Company> AddCompany(Company item)
{
    return base.AddAsync(item);
}

这带来了您可以做的另一个简化(和较小的性能增强):如果您要在您的方法中返回唯一 await 的结果,您可以取消 asyncawait in那个方法和just return the Task

【讨论】:

  • 它工作了很长时间。但突然间变得很奇怪。它调用控制器中的每一行代码5-6次。在此之后移动到存储库并调用每行代码 5-6 次。然后返回控制器,一切都在重复。
  • 如果你看到它击中Task&lt;IActionResult&gt; AddCompany 5-6 次,那么这意味着收到了 5-6 个请求。这不是 C# 代码中的错误。这是一个错误,但它被称为(JavaScript?)
  • 谢谢加布里埃尔。你是对的。单击任何按钮(获取或保存)后,jquery ajax 发送异步请求 9 次。在此之后,我收到 9 个成功结果。这对我来说似乎太不可能了,我什至不想浪费时间检查 ajax 请求。现在我看到这是可能的。但是我仍然无法想象是什么可以强制 ajax 发送 9 个请求而不是 1 个。有什么建议吗?
  • 我在 chrome 中检查了“元素”,它只显示了一个我的自定义 js 文件。
  • 如果没有看到 JavaScript 代码,我不能说。您可以将其添加到您的问题中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多