0

I'm using asp.net mvc to make a simple application where i have 3 pages divisions, employees and coffees.

database models

public abstract class BaseModel
{
    [Key]
    public int Id { get; set; }
}

public class Division : BaseModel
{
    public string Name { get; set; }
    public List<Employee> Employees { get; set; }

}

public class Employee : BaseModel
{
    public string Name { get; set; }
    public string FamilyName { get; set; }
    public string Function { get; set; }
    public Division Division { get; set; }
    public virtual ICollection<CoffeeBehavior> CoffeeBehaviors { get; set; }
}

frontend viewmodels

public class DivisionViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<EmployeeViewModel> Employees { get; set; }
}

public class EmployeeViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FamilyName { get; set; }
    public string Function { get; set; }
    public DivisionViewModel Division { get; set; }
    //public List<CoffeeBehaviorViewModel> CoffeeBehaviors { get; set; }

    public int SelectedId { get; set; }
    public List<DivisionListViewModel> divisions = new List<DivisionListViewModel>();
    public IEnumerable<SelectListItem> DivisionItems => new SelectList(divisions, "Id", "Name");
}

i can create divisions edit them whatsoever. However when i create an employee this results in a duplicate enty for divisions in my database.

instead of adding the employee to my existing division a new division is created with the same name and the employee is added to that one

[HttpPost]
    public ActionResult Create(EmployeeViewModel employee)
    {
        if (ModelState.IsValid)
        { 
            employee.Division = divisionService.GetDivision(employee.SelectedId);
            DivisionViewModel dv = divisionService.GetDivision(employee.SelectedId);
            employee.Id = employeeService.Create(employee);
            dv.Employees.Add(employee);
            divisionService.Edit(dv);
            return RedirectToAction("Index");
        }

        return View(employee);
    }

this is the create method. i figured it was because the employee didn't have a generated key yet so i created the employee first and then added it to the division followed by updating the divison in the database.

this resulted in the same duplication but i received an error on updating the division

Attaching an entity of type 'CoffeeManager.DAL.Models.Division' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

i know i'm missing something but i have no clue what it is.

tereško
  • 58,060
  • 25
  • 98
  • 150
Axel Bouttelgier
  • 173
  • 1
  • 12
  • When i change public Division Division { get; set; } to the Id because that's the only thing i really need from division the duplicate problem is solved but the original division isn't updated and calling the edit which calls an update method to the dB still gives the same error – Axel Bouttelgier Mar 07 '16 at 10:52
  • You might have a look at my answer on [ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value](http://stackoverflow.com/questions/23201907/asp-net-mvc-attaching-an-entity-of-type-modelname-failed-because-another-ent/39557606#39557606). – Murat Yıldız Sep 18 '16 at 12:31

1 Answers1

0

So i figured out what was wrong and it was a really dumb mistake. my logic is in the controllers on viewmodels which is totally wrong.

employeeService.Create(employee);

this should be the only thing that is here. the rest of the logic should be in the employeeservice.create method.

instead it should've been done directly on the database model.

public int Create(EmployeeViewModel employeeVm)
    {
        var employee = mapper.Map<Employee>(employeeVm);
        employee.DivisionId = employeeVm.SelectedDivisionId;
        return employeeRepository.Insert(employee);
    }

like that.

the reason why this is so is because of the tracking of entities. once the model is converted to a viewmodel EF can't track the entity anymore and as such it will be regarded as a new entity once it is converted back.

Axel Bouttelgier
  • 173
  • 1
  • 12