none
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.

    Question

  • I am getting this error, when calling submit changes....

    "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."

    I have read alot about it, and am pretty convinced that I can solve it.

    BUT I cant find it.  How can I identify the object reference that is causing this issue?

    • Moved by Noam Ben-Ami - MSFT1 Wednesday, September 09, 2009 7:07 PM (From:ADO.NET Entity Framework and LINQ to Entities)
    Thursday, July 23, 2009 1:18 PM

All replies

  • It would be great if you could show us some code, so we'll know what you're trying to do.

    Usually this message suggest one of two:

    1. You are using attach to attach an existing entity to your context, but that entity, or one of its referenced entities is new (doesn't have an entity key)
    2. You are using add to add a new entity to your context, but that entity has an entity key

    The easiest way to check is look at the entity in debug and if trying to attach, look at it's referenced entities (and their entities) and check if all are existing with an entity state that isn't "added"


    Please mark posts as answers/helpful if it answers your question
    Thursday, July 23, 2009 7:05 PM
  • That is exactly what I need to check. 

    How do I check the Entity State? I can see the enum, but can't find how to get it from my objects.

    Friday, July 24, 2009 7:35 AM
  • Every entity that is declared in EF derives from EntityObject, thus it inherits it's properties, among them, the EntityState property.

    Open the instance of the entity in watch window while debugging, look at it's base, and look for it's entity state.

    Another option is to use the object context's (your model) ObjectStateManager to get the entity's state:

    context.ObjectStateManager.GetObjectStateEntry(entity)

    This will return an ObjectStateEntry object which has a State property (this too of type EntityState)
    Please mark posts as answers/helpful if it answers your question
    Friday, July 24, 2009 7:44 AM
  • Here's some code....

    Each screen in my application is a User control which inherits from a base class which inherits from AvalonDock.DockableContent.

    When I instantiate my user control I create a new DataContext.  Each screen manages its own datacontext so I can easily throw changes away or save at will.
            public invoice()
            {
                InitializeComponent();
    
                DataContext = this;
                
                db = new ModelDataContext();
    
                EditMode = editModeEnum.readOnly;
            }
    

    The screen then loads up an invoice and ites items via bindings in the XAML.

    When the user comes to Cancel Changes, I throw the data context away.

            private void CancelCommand_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                // Store the current data item for use after we recreate the context.
                transact transact = this.transact;
    
                // Set the current data item to null, to prevent properties changing in the bindings when the context is changed.
                this.transact = null;
    
                // Create a new datacontext.  This creates a new business context, and other bindings in XAML that bind to business and db will refresh.
                db = new FBAModelDataContext();
    
                // Reload the data item from the new datacontext, only if there was one set before the command.
                if (transact != null)
                    this.transact = transact.Get(transact.ctranid, business);
    
                // Lock the screen from editing.
                EditMode = editModeEnum.readOnly;
            }
    
    

    Alternatively the Save, commits the changes.  For consistency it then calls a cancel to reload the context.

            private void SaveCommand_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                ValidationResult ValidationResult = this.Validate();
                if (ValidationResult == ValidationResult.ValidResult)
                {
                    // Update some properties and calculations of the data item that cant be done earlier...
                    invoice.recalculate();
    invoice.business = business; // current business context. (might get set to null, it any items where deleted) // if the data item is new, insert it. if (invoice.ctranid == 0) db.invoices.InsertOnSubmit(invoice); //else //{ // invoice.Detach();
    // db.transacts.Attach(invoice, true); //this doesnt work because my tables dont have timestamps. // db.items.AttachAll(invoice.items, true); //} // Correct for any items with incorrect data contexts. foreach (item item in invoice.items) item.business = invoice.business; // Save the changes. db.Log = new DebuggerWriter(); db.SubmitChanges(); // Refresh the screen. CancelCommand_Executed(sender, e); } else System.Windows.Forms.MessageBox.Show(ValidationResult.ErrorContent.ToString(), ((AssemblyTitleAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), true)[0]).Title, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); }






    Friday, July 24, 2009 7:52 AM
  • Can nobody answer this question?


    Using Linq there appears to be no manner to detect the name of the entity that is throwing the error....{"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."}


    I am not using the Entity Framework, so dont seem to have anything like the object statemanager.


    How can I identify what entity is throwing this error?

    Any help?
    Wednesday, September 09, 2009 1:22 PM
  • Can you provide more sample code showing what you're doing and/or what the different things are declared as?

    E.g. what is "transact"? What are invoice.business and invoice.items declared as?

    The commented .Attach and .AttachAll code - any chance that that happens elsewhere?
    Kristofer - Huagati Systems Co., Ltd. - Cool tools for Linq-to-SQL and Entity Framework: www.huagati.com/dbmltools (VS designer add-in), www.huagati.com/L2SProfiler (query profiler for L2S)
    Thursday, September 10, 2009 2:00 AM
  • THanks for your reply.

    More code for a full solution could become immense...I will try to explain better if it helps.


    I have created the App using LINQ to SQL.  To create the data layer I created a new assembly and added a "Linq to SQL Classes object to it".  My choice for Linq to SQL over the full Entity Framework was due to shortcomings in the Entity framework August 08, when I started this project.  In the LINQ designer I added my databasse tables, of which there are 100.  Any additional properties or methods, such as selecting lists of items, I create partial classes with Static Select methods accepting whatever parameters I need.

    So, for the most part the entities themselves come straight form the LINQ to SQL designer.

    At no point in my code do I call AttachAll.

    transact is a transaction; a sort of generic entity which incorporates invoices, sales notes, etc.

    A transaction has links to several enities and lists of entitiies, such as invoice items, a transaction type, accounting entries, etc.
    Each item has a link to a supplier (or customer), an item type, value, etc.
    there are many other relationships between various items which are mapped in the model designer.

    Some items are linked to each other via a composite key because different business users need unique data.  some data is shared between businesses in the same database.

    So you see, it is a complex model.

    In the example above, I loaded a transaction on my screen, and saved.  I made no attempt to make any changes.  But clearly, somewhere LINQ is making an incorrect reference.

    What I need to be able to do is to find out what entity is trying to be inserted when this error is thrown.

    I have tried crating a logwriter to log the SQL but it errors before getting there.
    Most items have a business reference.  business is an entity in the model which is unique for a business user.  I have tried to interogate most items to see that they belong to the same business, which tells me they are in the same context, but there are over 100 items, and some items are linked to more than one other entity.  I would have to check each entity to find one with the incorrect business, and some entities do not hold a business link so there is nothing (that I have added) to identify where they belong.

    Surely LINQ must track the context for an entity somewhere?

    THan ks.
    Thursday, September 10, 2009 11:14 PM

  • Surely LINQ must track the context for an entity somewhere?


    If you want to see what entities are queued for insert/update/delete, use the DataContext's GetChangeSet method. It will give you the objects that will be inserted/updated/deleted, but won't tell you the reason they're there.

    If you need to dig deeper than what the GetChangeSet gives, the next step would be to dig into what the change tracker knows about the objects. I have posted a code sample showing how to get hold of the L2S change tracker here:
    http://stackoverflow.com/questions/1321255/whats-the-cleanest-way-to-make-a-linq-object-dirty/1321616#1321616

    ...it doesn't do exactly what you need (in fact, it does almost the opposite :) ) but can be useful as a sample/starter just to see how to get hold of the L2S change tracker.
    Kristofer - Huagati Systems Co., Ltd. - Cool tools for Linq-to-SQL and Entity Framework: www.huagati.com/dbmltools (VS designer add-in), www.huagati.com/L2SProfiler (query profiler for L2S)
    Friday, September 11, 2009 6:08 AM
  • @KristoferA in my experience when I get this Exception a call to GetChangeSet() throws the same exception as referenced above which is super frustrating because the exception doesn't get enough detail to reasonably track down the issue.  It's like like "Contact your system admin" error message.


    Regards, Mike DePouw
    Wednesday, June 23, 2010 3:05 AM
  • Did you find an answer to this question?

    Im also using l2s, and getting that annoying exception when calling "GetChangeSet()" to see where the error occurs! I have no clue where to look for the error, and supplying code is therefore impossible!

     


    Tuesday, July 26, 2011 7:31 AM
  • It is normally not the changeset that is the issue, it is because you are using a different context.

    You could make a completly new context to make a detached update:

    var context = new DataClassesDataContext();
    
    var foo = from row in context.MyTable select row;
    
    var tuple = foo.First();
    
    tuple.property1 = myValue;
    
    context.SubmitChanges();
    
    


    Or figure out exactly how to toss your context around to get to the place you update.

    Tuesday, July 26, 2011 10:33 AM
  •  

    I know the cause of the problem (as the initial question by Jeffrey), which is entities created from another datacontext than is submitting them.

    The problem is therefore not why the problem occurs but finding a way to figurere out where it occurs, as the exception first is thrown when SubmitChanges is called.

     

    On a side note..
    I have now found the problem, and was caused by a static List populated by a prior datacontext. But I have no doubt I'll have this problem again!

     




    Tuesday, July 26, 2011 10:48 AM