Sql – “An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.”

asp.net-mvcdatabaselinq-to-sql

When I run following code:

public ActionResult Complete()
        {
            try
            {
                VeriTabanDataContext db = new VeriTabanDataContext();
                db.Persons.InsertOnSubmit(_person);
                db.SubmitChanges();
                return View(_person);
            }
            catch (Exception ex)
            {
                return RedirectToAction("Error", ex);
            }
        }

I'm getting following Exception, on SubmitChanges();

"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext.  This is not supported."
  • Here "_person" object is taken from Session and is a good standing. Note: _person is a result of multistep wizard and this is the place where I add new Person object to the DB.
  • My Person table has 9 relations and it's not ok for me to add version column for each of them as is suggested by some geeks around
  • I've investigated this problem a lot and spend 2 days on it and still couldn't solve it. Some of the workarounds that other suggest don't solve my problem, and others seem to be just dirty workaround. Do you experts have a good solution for this problem, considering that Person class has many relations and also it isn't ok to add a column to the tables.
  • I also want to note that I've tried to use 'db.Persons.Attach(_person) ' and setting db.DeferredLoadingEnabled = false; THis time I'm not getting any Exception but data is NOT saved to DB

Best Answer

I create a class called applicationController which derives from Controller. Then i make all of my controller classes derive from this. The applicationController class has a constrcutor which creates a new instance of my repository (or datacontext in your instance) which is used throughout the application:

     public class ApplicationController : Controller
     {
          private VeriTabanDataContext _datacontext;

          public ApplicationController() : this(new VeriTabanDataContext())
          {
          }

          public ApplicationController(VeriTabanDataContext datacontext)
          {
               _datacontext = datacontext;
          }

          Public VeriTabanDataContext DataContext
          {
               get { return _datacontext; } 
          }
     }

Then you can use this in all of your controllers

public class MyController : ApplicationController
{
     public ActionResult Complete()        
     {            
           DataContext.Persons.InsertOnSubmit(_person);              
           DataContext.SubmitChanges();                
           return View(_person);            
     }
}

Not on my PC with VS installed at the moment so not tested this code....

Hope this resolves the issue -Mark