1

I have one to many relationship in my web forms project. And always get the same error: "an entity object cannot be referenced by multiple instances of ientitychangetracker" . How can I solve this problem, and how can I add items in one to many relationships by using entity framework? Here is example code:

        MusicianManager mm = new MusicianManager();
        Musician m = new Musician();
        m.MusicianName = txtMusicianName.Text;
        m.MusicianSurname = txtMusicianSurname.Text;
        m.MusicianInstrument = txtInstrument.Value;

        CountryManager cm = new CountryManager();
        m.Country = cm.GetById(Convert.ToInt32(drpLstCountry.SelectedValue));

        int id = mm.Add(m);

CountryManager class:

using ROCK.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ROCK.DataAccess
{
public class CountryManager
{
    public Country GetById(int id)
    {
        RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities();
        return rde.Countries.FirstOrDefault(c => c.CountryId == id);
    }
}
}

MusicianManager classs:

using ROCK.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ROCK.DataAccess
{
public class MusicianManager
{
    public int Add(Musician m)
    {
        RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities();
        rde.Musicians.Add(m);
        rde.SaveChanges();
        List<Musician> m2 = rde.Musicians.OrderByDescending(mm => mm.MusicianId).Take(1).ToList();
        foreach (var item in m2)
        {
            return item.MusicianId;
        }
        return -1;

    }
}
}

I use Entire Design - (dataaccess, entity and userinterface.)

  • Take a look at this post: http://stackoverflow.com/questions/10191734/entity-object-cannot-be-referenced-by-multiple-instances-of-ientitychangetracker – Felipe Oriani Sep 15 '14 at 00:53
  • Thanks. I saw that post but I dont know the meaning of "creating a context outside of the service classes". So I open this post. Why Do I have to create context for the class? – Polat Dundar Sep 15 '14 at 00:59
  • where do you create context in your situation, do you have different context for MusicManager and CountyManager, and I think this is the issue. – J.W. Sep 15 '14 at 02:47
  • I think your managers shuld taje a context as parameter to be sure that both (Musician and Country) have the same context – tschmit007 Sep 15 '14 at 07:52
  • I edited the Question, I added MusicianManager and CountryManager classes. – Polat Dundar Sep 15 '14 at 16:55

1 Answers1

0

You have to understand that the Add method will trigger the Entity Framework to perform a DetectChanges operation. This operation will fix up all relations: i.e. it will adjust the navigation properties for both the new Musician as for the Country.

By calling Add the new Musician gets connected to the DbContext that you initialized within the CountryManager while it will also connect it to the DbContext that was initialized within the MusicianManager. For this to succeed at least one of these contexts must have change tracking disabled.

If you need more help please show us the constructors of the Managers and the code for the GetById function.

After seeing your updated code I advise you to change the lines:

RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities();

To a using block:

using(RockolektifDatabaseEntities rde = new RockolektifDatabaseEntities())
{
    //the code of the method
    return //the entity
}

This will make disappear the Exception about an entity being tracked by two contexts. But probably new Exceptions will surface.

After refactoring to the using blocks (what you must do as otherwise your application will start leaking memory) I would rewrite the code to:

MusicianManager mm = new MusicianManager();
    Musician m = new Musician();
    m.MusicianName = txtMusicianName.Text;
    m.MusicianSurname = txtMusicianSurname.Text;
    m.MusicianInstrument = txtInstrument.Value;

    CountryManager cm = new CountryManager();
    var country= cm.GetById(Convert.ToInt32(drpLstCountry.SelectedValue));
    if(country!=null) m.CountryId=country.CountryId;
    int id = mm.Add(m);    

This assumes that Musician has a foreign key named CountryId for its navigation property Country.

Dabblernl
  • 15,831
  • 18
  • 96
  • 148