none
Crash on Attach or InsertOnSubmit RRS feed

  • Question

  • Hi all,

    I'm getting the following error that I don't know what it's caused by:

     

    Code Snippet

    Object reference not set to an instance of an object.

       at System.Data.Linq.Mapping.EntitySetDefSourceAccessor`2.GetValue(T instance)
       at System.Data.Linq.Mapping.MetaAccessor`2.GetBoxedValue(Object instance)
       at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.get_HasDeferredLoaders()
       at System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(MetaType mt, Object obj, Dictionary`2 visited, Boolean recurse, Int32 level)
       at System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(Object obj, Boolean recurse)
       at System.Data.Linq.Table`1.Attach(TEntity entity, Boolean asModified)
       at Tradepoint.Services.Contacts.ContactRepository.Update(Contact obj) in

     

     

     

    Basically it's hitting this on the following line:

    dc.Contacts.Attach(obj, true); //This means the whole thing is modified.

     

    My system is disconnected and I'm reattaching it and then saving it. I never get to save it though because of the error on attach.

     

    The only things that are not instantiated before the save is the various collections of sub objects. They're all null.

     

    The problem is that these come from a WCF service and I can't get WCF to serialize/deserialize this kind of stuff:

     

    Code Snippet

    [Association(Name = "ContactContacts_LinkedContact", Storage = "_LinkedContacts", ThisKey = "ID", OtherKey = "LinkedContactID", IsForeignKey = true)]

    public EntitySet<ContactContacts> LinkedContacts {

    get {

    return this._LinkedContacts;

    }

    set {

    this._LinkedContacts.Assign(value);

    }

    }

     

     

    So I don't know what to do next to get this to pass back and save.  What am I doing wrong? How can I work around this and pass these with WCF?

     

    Thanks!

    Monday, April 28, 2008 8:54 PM

Answers

  •  

    You need to mark the object as datacontract and members of it as datamember to make it serializable via WCF. You can do it by opening dbml designer properties and changing serialization mode to Unidirectional .

     

    you can also use sql metal tool. for more info : http://msdn.microsoft.com/en-us/library/bb546184.aspx 

     

    Thanks,

     

    Sidar

    Tuesday, May 6, 2008 1:28 AM
  • It looks as if one of the EntitySet properties on the object is not initialized.  Has this object been deserialized?  If so, did you use the option in the designer to generate the unidirectional serialization capability?  The xml deserializer does not invoke the standard object constructor; it looks for an OnDeserializing method instead. The designer generates this method for you to make sure all the properties are properly initialized.

     

    Tuesday, May 6, 2008 2:01 AM
    Moderator

All replies

  •  

    You need to mark the object as datacontract and members of it as datamember to make it serializable via WCF. You can do it by opening dbml designer properties and changing serialization mode to Unidirectional .

     

    you can also use sql metal tool. for more info : http://msdn.microsoft.com/en-us/library/bb546184.aspx 

     

    Thanks,

     

    Sidar

    Tuesday, May 6, 2008 1:28 AM
  • It looks as if one of the EntitySet properties on the object is not initialized.  Has this object been deserialized?  If so, did you use the option in the designer to generate the unidirectional serialization capability?  The xml deserializer does not invoke the standard object constructor; it looks for an OnDeserializing method instead. The designer generates this method for you to make sure all the properties are properly initialized.

     

    Tuesday, May 6, 2008 2:01 AM
    Moderator
  •  

    Waw, I had no idea LINQ could put the DataContract and DataMember attributes on for you - I was doing it in partial classes before I read this post; looked quite messy and hard to maintain... Microsoft should have made it more obvious that LINQ and WCF are so compatable. Oh well, good job they implemented this feature!

     

    Thanks guys!

    Wednesday, July 2, 2008 12:23 PM
  • At a guess then code is failing when it tries to lazy load a child collection of your Contact class. Don't forget that collections are lazy loaded by default and when the collection is accessed you need to have the DataContext that loaded the option in scope in order to retrieve those items. If you have serialized the object across tiers, but not loaded the children prior to that, then you may still have a reference to a DataContext to load them with that is no longer in scope. If you pass objects across tiers you need to make sure that you have loaded their graph.

    See: http://codebetter.com/blogs/ian_cooper/archive/2008/06/28/architecting-linq-to-sql-part-9.aspx

    Friday, July 4, 2008 8:44 AM
  • Indeed, distributed architectures make you think about where your DataContext should reside.

     

    I was faced with the decision between instantiating per connection, per class (e.g. manager/controller), or per method. After consideration, I chose per class (in my case, the class which looks after create/read/update/delete for each LINQ data type); this way, methods within the class can talk to each other on the same context. When you try to use multiple DataContext instantiations in one scenario (where you're reading and updating for example) you'll run unto problems. If I were to use a DataContext for each method, I would have had to pass the DataContext around to every method - which could be quite messy... maybe.

     

    Really, you just have to weigh up the pros and cons of instantiating the DataContext in a particular place, and see what has the least disadvantages.

     

    Hope this helps someone!

    Friday, July 4, 2008 10:09 AM
  • This problem happens when you overload the constructor in the partial class, and not call the default constructor in it.

    The default constructor of the entity does few things thats required by the Context object.

    Hence if you have an overloading constructor in your partial class and using it to create the object, make sure the default constructor is called in the first line

    in C# you can do this by

    eg.

     
    Customer
    (
    string
     custID
    )
    

    you need to add a

     
    Customer
    (
    string
     custID
    ):
    this
    ()
    

    in C# where Customer is my class and Customer(string custID):this() is my overload constructor in my partial class.


    Franco S.
    Thursday, July 22, 2010 5:33 PM