Search code examples
asp.netdatabasereactjsentity-frameworkcode-first

Duplicate entries when adding new entries to DB with entity framework triggered via React GUI


I inherited an existing project in ASP.net/C# using the entity framework with code-first approach. I defined a new table and successfully did all the migration necessary so that the [myProject].[ExportFiles] is indeed visible as table in the database.

The following code works fine, except that it always creates double database entries. I am sure that the code is only called once, I checked that using breakpoints. Assume that my datbase context is called _db.

namespace myProject.Service
   {
      public void Export(int userId)
         {
            var currentExportTimestamp = DateTime.Now;
            var currentUserId = 42;
            var exportRecord= new ExportFiles // defining a new entry
               {
                  FileName = cashflowFileName,
                  DateSubmitted = currentExportTimestamp,
                  UserId = currentUserId,
               };
           _db.ExportFiles.Add(exportRecord); // nothing written in DB yet
           _db.SaveChanges(); // the entry is written to DB, but twice
         };
   };

The curious thing: The code above always writes two new records with increasing Ids, although it has only has a single reference, the ExportController.cs looks roughly as follows:

[Route("api/Export", Order = -1)]
[HttpPost]
public IHttpActionResult Export(int? selectedEntityId, DateTime? selectedDate)
   {
      var name = System.Web.HttpContext.Current.User.Identity.Name;
      var userId = _userService.GetUserByName(name).Id;

      if (selectedDate == null || selectedEntityId == null)
         {
            return BadRequest("Need to select appropriate data");
         }
      try
         {
            _export.Export(userId);
            return Ok();
         }
   }

My debugging exercise revealed that this controller is already called twice, but I am not sure why.

The component MyView.tsx looks as follows:

export interface MyViewProps {
    selectedDate: any,
    selectedEntity: number,
    exportStatus: boolean
    setExportingStatus: (exportingStatus: boolean) => void;
    selectDate: (date: any) => void;
    selectEntity: (entityId: number) => void;
    exportDispatch: () => void;
}

export class MyView extends React.Component<MyViewProps, any> {
    constructor(props) {
        super(props);
        this.handleExport = this.handleExport.bind(this);
    }
    handleExport() {
        this.props.setExportingStatus(true); 
        this.props.exportDispatch();
    }

    render() {  
        return (
            <div>
                <Button
                    type="primary"
                    onClick={this.handleExport}
                    disabled={this.props.exportStatus == true}
                    > Export
                </Button>
            </div>
        );
    }
}

Additional information needed

The data model reads:

namespace myProject.Entity.Models
{
    public class ExportFiles
    {
        public int Id { get; set; }
        public string FileName { get; set; }
        public DateTime DateSubmitted { get; set; }
        public int UserId { get; set; }
        public virtual User User { get; set; }
    }
}

The currentUserId = 42 does exist as foreign key in the table User.

Edit

I figured that that the function is actually called twice, but I do not understand why.

Related questions


Solution

  • Your code it's correct, checking whether the DateSubmitted value is the same in both of your duplicate values will tell you if indeed your record it's being duplicated by the .SaveChanges() method or if you are just calling the entire method twice.

    Edit: Since you added the React Code i can see that you are registering to the event without needing it since you already are triggering it with the button click so this this.handleExport = this.handleExport.bind(this); is creating the duplicate requests

    export class MyView extends React.Component<MyViewProps, any> {
        constructor(props) {
            super(props);
        }
        handleExport() {
            this.props.setExportingStatus(true); 
            this.props.exportDispatch();
        }
    
        render() {  
            return (
                <div>
                    <Button
                        type="primary"
                        onClick={this.handleExport}
                        disabled={this.props.exportStatus == true}
                        > Export
                    </Button>
                </div>
            );
        }
    }