locked
Exception When Saving RRS feed

  • Question

  • Hi,

    I am receiving the dreaded "Non-static method requires a target" exception when calling the SaveChanges method on a proxy to a Data Service.
    The entity I'm trying to save was added to its respective collection through the AddObject method, and it does show up in the Entities collection. I have also added a link, through the AddLink method, that relates it with another object which is associated with the entity I'm trying to save.

    What could be the cause, any clues?

    Thanks,

    Ricardo Peres
    Monday, November 16, 2009 11:18 AM

Answers

  • First question: the exception is thrown because the server is expecting the POST object to have at least one Author, so instead of
    proxy.AddLink(posts [ 0 ].Author, "Post", p);

    you should try

    proxy.AddLink(P, "Authors", posts[0].Author);

    provided that "Authors" is the correct navigation property name, and that posts and authors is 0..1-* relationship.
    (If each post contains only one author, then use SetLink instead).

    The second question: EF codegen is different from data service code gen, we currently do not support carrying the same entities across multiple tiers. While you can use those entities on the server, the data service client require that you generate the client entities using DataSvcUtils, or Add Service References.

    Regards,
    PQ


    Peter Q. http://blogs.msdn.com/peter_qian
    Thursday, November 19, 2009 1:52 AM
    Answerer

All replies

  •  

    Hello,
    Does your client see the error message when you try to browse to the Data Service endpoint or a specific Entity Set (ex: /Customers) ? Can you browse to the Data Service in the browser ?

    Thanks,
    Monica
    Monday, November 16, 2009 7:59 PM
    Moderator
  • Also if you could share the callstack of the exception, it will provide us with more information about where/when the error occurs.

    Thanks,
    Vitek Karas [MSFT]
    Monday, November 16, 2009 10:26 PM
    Moderator
  • Hello,

    Here is the stack trace:

       at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Data.Services.Client.DataServiceContext.WriteContentProperties(XmlWriter writer, ClientType type, Object resource)
       at System.Data.Services.Client.DataServiceContext.WriteContentProperties(XmlWriter writer, ClientType type, Object resource)
       at System.Data.Services.Client.DataServiceContext.WriteContentProperties(XmlWriter writer, ClientType type, Object resource)
       at System.Data.Services.Client.DataServiceContext.CreateRequestData(ResourceBox box, Boolean newline)
       at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.CreateChangeData(Int32 index, Boolean newline)
       at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.BeginNextChange(Boolean replaceOnUpdate)
       at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)
       at System.Data.Services.Client.DataServiceContext.SaveChanges()
       at DataTest.DataServices.DataServicesRepository.Save() in C:\CVSCritical\users\r-peres\projects\DataTest\DataServices\DataServicesRepository.cs:line 43
       at DataTest.Test.Program.Main(String[] args) in C:\CVSCritical\users\r-peres\projects\DataTest\Test\Program.cs:line 33
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

    DataServicesRepository is a class I built that wraps a DataServiceContext in a known interface (my IRepository).
    The service is using an Entity Famework context and I can navigate through all of the entities.
    My code looks like this:

    using

     

    (Repository repository = new DataServicesRepository(@"http://localhost:3769/DataServicesService.svc"))

    {

     

    var posts = repository.Lookup<DataTest.EntityFramework.Post>().ToList();

    DataTest.EntityFramework.

    Post p = new DataTest.EntityFramework.Post();

    p.Author = posts [ 0 ].Author;

    p.Title =

    "Teste Title";

    p.Body =

    "Teste Body";

    p.Modified =

    DateTime.Today;

    p.Created =

    DateTime.Today;

    repository.Add(p);

    repository.Save();

    }

    The Add method uses reflection to add all links and calls AddObject. Save calls SaveChanges.

    Thanks,

    RP

    Tuesday, November 17, 2009 10:42 AM
  • Hi,

     

    Are you using the Entity Data Model auto-generated entities classes to hold the result which is retrieved from ADO.NET Data Services?   If so, please use the classes generated by the ADO.NET Data Services reference instead. 

     

    Here is one related thread, http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/2f50bba8-032d-4a3b-ab39-e2890727dc44. 

     

    If you have any questions, please feel free to let me know.

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, November 18, 2009 10:10 AM
    Moderator
  • Hi,

    I've switched to the classes generated by datasvcutil, instead of the Entity Framework ones, now the error is different:

    Entities in 'BlogEntities.Post' participate in the 'FK_Post_Author' relationship. 0 related 'Author' were found. 1 'Author' is expected.

    However, I am doing this:

    var

     

    posts = ... //list of posts where the Author property is expanded

    BlogModel.

    Post p = new BlogModel.Post();

    p.Author = posts [ 0 ].Author;

    p.Author.Post.Add(p);

    p.Title =

    "Teste Title";

    p.Body =

    "Teste Body";

    p.Modified =

    DateTime.Today;

    p.Created =

    DateTime.Today;

    proxy.AddObject(

    "Post", p);

    proxy.AddLink(posts [ 0 ].Author,

    "Post", p);

    proxy.SaveChanges();

    Any clues?

    Thanks,

    RP

    Wednesday, November 18, 2009 11:42 AM
  • By the way, why wont the Entity Framework generated classes work?
    The model is pretty simple:

    Author has Blogs <-> Blog has Author
    Blog has Posts <-> Post has Blog
    Post has Comments <-> Comment has Post
    Post has Tags <-> Tag has Posts
    Post has Attachments <-> Attachment has Post

    Thanks,

    RP
    Wednesday, November 18, 2009 7:54 PM
  • First question: the exception is thrown because the server is expecting the POST object to have at least one Author, so instead of
    proxy.AddLink(posts [ 0 ].Author, "Post", p);

    you should try

    proxy.AddLink(P, "Authors", posts[0].Author);

    provided that "Authors" is the correct navigation property name, and that posts and authors is 0..1-* relationship.
    (If each post contains only one author, then use SetLink instead).

    The second question: EF codegen is different from data service code gen, we currently do not support carrying the same entities across multiple tiers. While you can use those entities on the server, the data service client require that you generate the client entities using DataSvcUtils, or Add Service References.

    Regards,
    PQ


    Peter Q. http://blogs.msdn.com/peter_qian
    Thursday, November 19, 2009 1:52 AM
    Answerer
  • Thanks, Peter, it worked perfectly!
    It was lacking the SetLink... how foolish of mine... :-(
    By the way: does the 1.5 CTP support Entity Framework's or LINQ to SQL's generated entities? If not, are there plans for this support?

    Thanks,

    RP
    Thursday, November 19, 2009 10:19 AM
  • Hi,

    We had looked into supporting the EF codegen (especially the EF2 self tracking entity) classes on the client tier before, but we didn't have too much cycle to spare. We will definitely revisit this sometime in the future, but it will not be a high priority thing. Currently neither V1.5 CTP nor .net 4.0 beta 2 support EF code gen.

    Regards,
    PQ
    Peter Q. http://blogs.msdn.com/peter_qian
    Thursday, November 19, 2009 11:26 AM
    Answerer
  • Hi,

    The 1.5 CTP doesn't suppor the entities generates by EF either. Currently we don't have plans to support this in the next version. I'm just wondering why do need it? We have our own code generation which works regardless of the server implementation. It's usually a good idea to separate the client and server types (for example for versioning purposes).

    Note that especially for EF the entities generated by EF rely on EF classes which will not work correctly without EF actually creating these entities.
    Same goes for ADO.NET Data Services (now WCF Data Services), the generated classes in some cases use supporting types from our client library, these types might not work correctly if you would use these classes in a different context (for example EF).

    Thanks,
    Vitek Karas [MSFT]
    Thursday, November 19, 2009 11:27 AM
    Moderator
  • Vitek and Peter,

    I understand what you mean, thanks for your help.

    Regards,

    RP
    Thursday, November 19, 2009 12:43 PM