Saving an Item in EF with existing childrens

Im having some problems saving an object (FeatureType) that have a 1-M relationship with Section.

public class FeatureType
    {
        public int Id { get; set; }

        public string Name { get; set; }

        [ForeignKey("SectionId")]
        public Section Section { get; set; }

        public virtual List<ItemType> ItemTypes { set; get; }
    }

    public class Section
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public int Order { get; set; }

        public virtual List<FeatureType> Features { get; set; }
    }

If The ItemTypes are new i have no problem and the insert is done correctly.

But if i want to add some existing ItemTypes im getting this Error:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

I have been reading about this problem but i havent found a way to solve it, and it might be because of how its designed my application.

Whem im mappinig from my viewModel to my Model, im getting the section ID and getting the section Object from my SectionRepository as this:

 private Section GetSection()
        {
            var section = _sectionRepository.GetSection(SectionId);
            return section;
        }

And this is what is giving me the problem, as the section is now been tracked by the SectionRepository that have its own context.

How can i solve this? I have tried just creating a new section with the existing ID but it just create me an empty object.

private Section GetSection()
            {
                var section = new Section{Id=SectionId};
                return section;
            }

UPDATE

To save my entity i just use :

_repository.Create(featureType.ToModel());

    public FeatureType ToModel()
        {
            var ft = new FeatureType
                         {
                             Name = Name,
                             ControlType = (ControlType)ControlType,
                             Order = Order,
                             Required = Required,
                             RequiredText = RequiredText,
                             ItemTypes = GetItemTypes().ToList(),
                             Section = GetSection(),
                         };

            return ft;
        }

UPDATE 2: This is how i have my repositories, i wouldn't like to manage any EF in my controller but with some kind of repository or service.

 public class EFBaseRepository
    {
        protected MyContext Db = new MyContext();

        public void Dispose(bool disposing)
        {
            Db.Dispose();
        }
    }

 public class EFFeatureTypeRepository : EFBaseRepository, IFeatureTypeRepository
    {
        public IQueryable<FeatureType> GetFeatureTypes
        {
            get { return Db.FeatureTypes.Include("Section").Include("ItemTypes"); }
        }

 public Message Create(FeatureType feature)
        {
            try
            {
                Db.FeatureTypes.Add(feature);
                Db.SaveChanges();
                return new Message();
            }
            catch (Exception e)
            {
                throw;
                // return new Message(e, string.Format("Error Creating {0}", feature.GetType()));
            }
        }

//..Other Methods
}

Answers


You say that the SectionRepository has its own context. That is going to cause you problems. The repositories should share a context. The context is a combination of the unit of work and repository patterns. You need to separate the two patterns:

How to migrate towards unit-of-work and repository pattern

EDIT

You can avoid having the DbContext in the Controller by implementing your own Unit Of Work pattern.

public interface IUnitOfWork : IDisposable
{
    ISectionRepository SectionRepository {get;}
    //etc

    int Save();
}

then in your controller:

public ActionResult Create(FeatureTypeCreate featureType)
{
   _Uow.SectionRepository.Create(featureType.ToModel());
   _Uow.Save(); //Saving is the responsibility of the Unit Of Work 
                //not the Repository
}

More references:

Implementing the Repository and Unit of Work

Repository and Unit of Work in Entity Framework

John Papa's original source code


Simply, the error you're getting means that the entities were returned from a different instance of your DbContext than from which they are now trying to be saved. Make sure that you're not doing something like using two different usings around your repository and that your repository always makes use of the same DbContext per instantiation.


Need Your Help

PDF font sizes are off - HTML to PDF via UI/WKWebView and UIPrintPageRenderer

html ios css pdf fonts

I need to create nice looking and exact PDFs inside my app. Due to various restrictions, I settled with HTMLs and a custom UIPrintPageRenderer. This works nicely so far.

Generating bundle.js with webpack & gulp

javascript gulp bundle webpack

I have configured gulp &amp; webpack to generate a bundle.js file, take a look the code below: