0
votes

I have a ASP.Net MVC form that is bound to the following view model. The form allows one submission to insert a new staff record along with all his phone numbers and appointment types. The controller [HttpPost] action using LINQ to SQL could do single record insert to the tables that are associated with the People(aka Staff) table except the EContactInfo and AppointmentType tables. The _StaffSerivce.Add() simply executes InsertOnSubmit() of that entity in the data repository. After all the new records are added, then the _Service.Save() is called where the SubmitChanges() of the data repository is executed. That's when I got an error saying "Cannot add an entity with a key that is already in use". The error is upon inserting the first phone number or appointment type, the primary keys of those tables are not changed after the first record is inserted in the respective table. How can I batch insert many records into ONE table? Thanks.

public class RequestForAppointmentViewModel
{
    public People Staff { get; set; }   /* Person to be appointed or employeed */
    public Appointment Appointment { get; set; }
    public ContactAddress PostAddress { get; set; }

    //public IList<EContactInfo> ContactMethods { get; set; }
    public string WorkPhone { get; set; }
    public string HomePhone { get; set; }
    public string CellPhone { get; set; }
    public string Pager { get; set; }
    public string EmailAddress { get; set; }

    //public IList<AppointmentType> AppointmentTypes { get; set; }
    public bool ChiefResident { get; set; }
    public bool CompPen { get; set; }
    public bool Consultant { get; set; }
    public bool ContractAppointmentType { get; set; }
    public bool FeeBasis { get; set; }
    public bool Locum { get; set; }
    public bool SpecialFellow { get; set; }
    public bool StaffAppointmentType { get; set; }
    public bool StaffFullTime { get; set; }
    public bool StaffIntermittent { get; set; }
    public bool StaffPartTime { get; set; }
    public bool StaffPermanent { get; set; }
    public bool StaffTemporary { get; set; }
    public bool WOC { get; set; }

    public Contract Contract { get; set; }
    public ContractingCompany ContractingCompany { get; set; } /* person is via contracting company */
}

The postback action has the following

        [HttpPost]
    public ActionResult CreateRequestForAppointment(RequestForAppointmentViewModel requestForm)
    {
        bool success = false;
        string alpha = string.Empty;

        if (!ModelState.IsValid)
            return View("RequestForAppointment", requestForm);
        else
        {
            try
            {
                People thisPerson = new People();
                if (TryUpdateModel<People>(thisPerson, "Staff")) //prefixed
                {
                    #region persist People
                    _staffService.Add(thisPerson);
                    alpha = thisPerson.LName.Substring(0, 1);
                    #endregion persist People

                    #region persist Appointment
                    Appointment thisAppointment = new Appointment();
                    if (TryUpdateModel<Appointment>(thisAppointment, "Appointment"))
                    {
                        thisAppointment.People = thisPerson;
                        _staffService.Add(thisAppointment);
                    }
                    #endregion persist Appointment

                    #region persist ContactAddress
                    ContactAddress thisAddress = new ContactAddress();
                    if (TryUpdateModel<ContactAddress>(thisAddress, "PostAddress"))
                    {
                        thisAddress.People = thisPerson;
                        thisAddress.Country = _staffService.ListCountries().SingleOrDefault(c => c.CountryName.Equals("USA"));
                        _staffService.Add(thisAddress);
                    }
                    #endregion persist ContactAddress

                    #region persist Contract Company
                    ContractingCompany thisCompany = new ContractingCompany();
                    if (TryUpdateModel<ContractingCompany>(thisCompany, "ContractingCompany"))
                    {
                        _staffService.Add(thisCompany);
                    }
                    #endregion persist Contract Company

                    #region persist Contract
                    Contract thisContract = new Contract();
                    if (TryUpdateModel<Contract>(thisContract, "Contract"))
                    {
                        thisContract.Appointment = thisAppointment;
                        thisContract.ContractingCompany = thisCompany;
                        _staffService.Add(thisContract);
                    }
                    #endregion Persist Contract

                    #region persist EContactInfo
                    if (!string.IsNullOrWhiteSpace(requestForm.WorkPhone))
                    {
                        EContactInfo WorkPhone = new EContactInfo();
                        WorkPhone.People = thisPerson;
                        WorkPhone.CodeReference = _staffService.ListMessagingMethods().SingleOrDefault(m => m.Description.Equals("Work Phone"));
                        WorkPhone.ContactDetail = requestForm.WorkPhone;
                        _staffService.Add(WorkPhone);
                    }

                    if (!string.IsNullOrWhiteSpace(requestForm.HomePhone))
                    {
                        EContactInfo HomePhone = new EContactInfo();
                        HomePhone.People = thisPerson;
                        HomePhone.CodeReference = _staffService.ListMessagingMethods().SingleOrDefault(m => m.Description.Equals("Home Phone"));
                        HomePhone.ContactDetail = requestForm.HomePhone;
                        _staffService.Add(HomePhone);
                    }

                    //others phones are omitted for abbreviation
                    #endregion persist EContactInfo

                    #region persist AppointmentType
                    if (requestForm.ChiefResident.Equals(true))
                    {
                        AppointmentType ChiefResident = new AppointmentType();
                        ChiefResident.Appointment = thisAppointment;
                        ChiefResident.CodeReference = _staffService.ListAppointmentTypes().SingleOrDefault(t => t.Description.Equals("Chief Resident (CRES)"));
                        _staffService.Add(ChiefResident);
                    }
                    if (requestForm.CompPen.Equals(true))
                    {
                        AppointmentType CompPen = new AppointmentType();
                        CompPen.Appointment = thisAppointment;
                        CompPen.CodeReference = _staffService.ListAppointmentTypes().SingleOrDefault(t => t.Description.Equals("Comp & Pen (C&P)"));
                        _staffService.Add(CompPen);
                    }
                   //Other types omitted for abbreviation
                    #endregion persist AppointmentType

                _staffService.Save();

                    success = true;
                }
            }

The repository methods are as follows.

 public class ClinicalPrivilegeRepository : IClinicalPrivilegesRespository
{
    private DB db = new DB();

    #region EContactIfo

    public IQueryable<EContactInfo> GetEContactInfoByPersonId(int id)
    {
      var eContactInfos = (from e in db.EContactInfos
                          select e).Where(e => e.FK_People.Equals(id));
      return eContactInfos;
    }

    public EContactInfo GetEcontactInfoById(int id)
    {
      var eContactInfo = (from e in db.EContactInfos
                          select e).SingleOrDefault(e => e.PKey.Equals(id));
      return eContactInfo;
    }

    public void Add(EContactInfo newEContactInfo)
    {
      db.EContactInfos.InsertOnSubmit(newEContactInfo);
    }

    public void Delete(EContactInfo thisEContactInfo)
    {
      db.EContactInfos.DeleteOnSubmit(thisEContactInfo);
    }

    #endregion EContactIfo

#region StaffAppointmentType

    public IQueryable<AppointmentType> ListStaffAppointmentTypes(int appointmentId)
    {
        IQueryable<AppointmentType> appointmentTypes = (db.AppointmentTypes.Where(t => t.FK_Appointment.Equals(appointmentId)).Select(t => t));
        return appointmentTypes;
    }

    public AppointmentType GetStaffAppointmentType(int appointmentId, int appointmentTypeId)
    {
        var appointmentType = (from t in ListStaffAppointmentTypes(appointmentId)
                                   select t).SingleOrDefault(x=>x.FK_AppointmentType.Equals(appointmentTypeId));
        return appointmentType;
    }

    public void Add(AppointmentType newAppointmentType)
    {
        db.AppointmentTypes.InsertOnSubmit(newAppointmentType);
    }

    public void Delete(AppointmentType thisAppointmentType)
    {
        db.AppointmentTypes.DeleteOnSubmit(thisAppointmentType);
    }

    #endregion StaffAppointmentType

public void Save()
    {
        //throw new NotImplementedException();
        db.SubmitChanges();
    }
}

}

1
The error you are getting is from Entity Framework so I added that tag. Please add the code for your _service.Save method since that is where the error is occurring in the stack (I would assume).kingdango
Thanks for the comment. I am using LINQ to SQL, not EF. I added the save() method in my original post.user266909
My apologies I jumped the gun. :-)kingdango

1 Answers

0
votes

The code are mostly correct. The real problem was in the EContactInfo and AppointmentType tables of the DBML I forgot to set the identity of the primary key true.