-2

I just migrated to mvc net core 3.0 from net core 2.2. Now each time when I am trying to add a new record to database the application creates 9 copies of the same record in DB. I have many tables in my Db and this happens on every one of them. When I was using net core 2.2 everything worked fine.

I am using this code to add a new record to DB:

Db context file:

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

This function is called from repository that is called from the controler:

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

The controller is called from jquery ajax on the client side and the request to the controller is sending on Add button click.

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

I can see on the screen "start" alert 9 times. After a while I can see "success" alert 9 times.

When I am trying to trace the code in debuger, I can see that execution goes chaotically from one function to another - several times one line of code in one function, after this several times in another function. After this it returns to another line of the first function and everything repeates 5-10 times.

And the most weird is that all these 9 records are normaly saved in MS server Db. They have all fields and keys. But when I am opening any of them on the screen It shows that all fields are empty. But using the same application I still can normaly open and see on the screen the records that were saved before I moved to Core 3.0

  • 6
    Incomplete. Do the 9 copies have the same Id? Any overrides of SaveChanges? How do you call this method? When you set a breakpoint here, how often is it hit? etc. – H H Oct 21 '19 at 19:53
  • 1
    "execution goes chaotically from one function to another" means you run on multiple threads (requests). So show us how/when you call AddCompany(). – H H Oct 21 '19 at 22:33

1 Answers1

0

I don't see any reason in the code you've given why it would save a record more than once.

I can see that execution goes chaotically from one function to another

This is normal if there are multiple threads running. While debugging, there is a "Thread" drop-down in the toolbar of Visual Studio. When you see it "jump" to another part of the code, notice that the thread number selected in that drop-down is different.

But this might suggest that multiple requests are being processed (i.e. you're actually sending 9 requests). You should be able to verify that on the client side (whatever the client is) or you can remove all your breakpoints, and set only one in your controller action:

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

When that breakpoint is hit, press F5. And just count how many times that breakpoint is hit.

As a side note, I don't really understand what you're doing here:

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

If the item was saved correctly, then savedItem.Id will have a value (assuming that is the primary key, generated by the database?). So why would you need to search for it to see if it's there? After all, if it didn't save successfully, there would have been an exception thrown.

Then why would you return exist if it's null? Mind you, that would never happen for the same reason (if it didn't save, an exception would have been thrown and you would never get to that line of code).

I feel like you could simplify that to this:

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

And that brings up another simplification (and minor performance enhancement) you can do: If you are going to return the result of the only await in your method, you can do away with async and await in that method and just return the Task.

  • It worked fine for the long time. But suddenly it became weird. It calls each line of code in controller 5-6 times. After this moves to the repositories and calls 5-6 times each line of code. Then returns back to the controller and everything is repeating again. –  Oct 22 '19 at 12:44
  • 2
    If you see it hitting `Task AddCompany` 5-6 times, then that means that 5-6 requests were received. That's not a bug in your C# code. That's a bug in however this is being called (JavaScript?) –  Oct 22 '19 at 12:46
  • Thank you Gabriel. You were right. After I click any button (get or save) jquery ajax sents async request 9 times. After this I am receiving 9 success results. It seemed so impossible for me that I even didn't want to waste my time checking ajax requests. Now I see it is possible. But I still can't imagine what can force ajax to send 9 requests instead of one. Any suggestions? –  Oct 22 '19 at 13:37
  • I checked "elements" in chrome and it shows only one my custom js file. –  Oct 22 '19 at 13:38
  • 2
    I couldn't say without seeing that JavaScript code. You could add it to your question. –  Oct 22 '19 at 13:41