locked
How to update a record using Ria Service? RRS feed

  • Question

  • In my domain service, i created a custom Update function to update the Employee; somehow nothing got updated to the DB. Is there something wrong in my code? Is it valid? Or am i missing something? I was able to get to the UpdateEmployee function in debug mode, but I don't see any changes in the DB. Any input is appreciated.

    I call the UpdateEmployeeByID function from a childwindow.

    MyProject.Web.Services.MyProjectDomainContext context = new MyProject.Web.Services.MyProjectDomainContext();
    context.UpdateEmployeeByID(100, 1, DateTime.now);

    custom function:

    [ServiceOperation]
    public void UpdateEmployeeByID(int ID, int status, datetime orderDate)
    {
       
    Employee e = GetEmployeeByID(ID);
        e.Status = status;
        e
    .ClosedDate = orderDate;

        UpdateEmployee(e);
    }

    //[RequiresAuthentication()]
    public void UpdateEmployee(Employee currentEmployee)
    {
       
    this.Context.AttachAsModified(currentEmployee, this.ChangeSet.GetOriginal(currentEmployee));
    }

    Thursday, August 13, 2009 7:56 PM

Answers

  • Sorry, I wasn't quite clear. It's really a 2-step change.

      1) Convert UpdateEmployeeByID to a custom method or possibly just write it yourself on the client

      2) Call SubmitChanges

    If you have the Employee loaded on the client, the following might be a bit easier. This is with a custom method.

      Employee emp = context.Employees.SingleOrDefault(e => e.id == 100);
      if (emp != null)
      {
        emp.UpdateStatus(1, DateTime.Now);
      }
      context.SubmitChanges();

    If you don't want to use a custom method, you could try this alternative.

      Employee emp = context.Employees.SingleOrDefault(e => e.id == 100);
      if (emp != null)
      {
        emp.Status = 1;
        emp.ClosedDate = DateTime.Now;
      }
      context.SubmitChanges();

    In both cases, you're looking up the Employee on the client side. If this isn't practical, then a service operation might be your best option. Just make sure to run this.Context.Submit at the end of the operation to persist the changes.

    Kyle

    Friday, August 14, 2009 12:35 PM
  • so here's my result:

    code behind from the xaml:

    context.UpdateEmployeeByID(100, "Completed", DataTime.Now);

    Domain Service:

    [ServiceOperation]
    public void UpdateEmployeeByID(int ID, string Status, DateTime dt)
    {
         Employee emp = this.context.employees.first(e => e.id == ID);
         if(emp != null)
         {
              e.status = Status;
              e.ShippedDate = dt;

              this.context.SaveChanges();
         }
    }

    and this works. Anything wrong with this? Thank you.

    Friday, August 14, 2009 1:56 PM

All replies

  • In general you shouldn't use service operations for updates, because this will have several bad consequences. Instead you should use a CustomMethod like:

    [CustomMethod]
    public void UpdateEmployeeCustom(Employee currentEmployee, int status, datetime orderDate)
    {
    }

    Thursday, August 13, 2009 8:36 PM
  • The reason this does not work is that submitting a changeset behaves differently your domain service than invoking a service operation. When you invoke SubmitChanges on the domain service, it will call each of your update methods and then submit all those changes to the DB (using this.Context.Submit or something similar). Like Petr said, a custom method would be a good option. In addition to the domain service changes, it would require a slight change to your client code which might be something like this.

      context.UpdateEmployeeByID(100, 1, DateTime.now);
      context.SubmitChanges();

    Kyle

    Friday, August 14, 2009 9:31 AM
  • Kyle,

    thank you for the reply. I left everything the way it is, and added

    context.SubmitChanges();

    nothing happens. The functions got called, but the db is not getting updated.

    i'm wondering if i have to assign value to the other fields or not, like when i inserting a record. however, this is just updating an existing record.

    Friday, August 14, 2009 12:05 PM
  • Petr,

    thank you for the reply also. Now i'm having a hard time converting an entity to a MyProject.Web.Employee object.

    in my service i have this function

    public Employee GetEmployeeByID(int ID)
    {
     var query (from e in this.context.employee
         where e.id == ID
         select e);

     if(query != null)
     {
       foreach(Employee emp in query)
       {
         query = null;
         return emp;
       }
     }

     return null;
    }

    // code behind the childwindow
    what i don't know how to do is, call the above function and covert the result to MyProject.Web.Employee;
    i tried:

    MyProject.Web.Employee emp;
    var query = context.GetEmployeeByID(100); // entity


    // how do i convert an entity to MyProject.Web.Employee so that I use your function? Sorry and thanks for helping me out. I'm just new to this.

     

    Friday, August 14, 2009 12:14 PM
  • Sorry, I wasn't quite clear. It's really a 2-step change.

      1) Convert UpdateEmployeeByID to a custom method or possibly just write it yourself on the client

      2) Call SubmitChanges

    If you have the Employee loaded on the client, the following might be a bit easier. This is with a custom method.

      Employee emp = context.Employees.SingleOrDefault(e => e.id == 100);
      if (emp != null)
      {
        emp.UpdateStatus(1, DateTime.Now);
      }
      context.SubmitChanges();

    If you don't want to use a custom method, you could try this alternative.

      Employee emp = context.Employees.SingleOrDefault(e => e.id == 100);
      if (emp != null)
      {
        emp.Status = 1;
        emp.ClosedDate = DateTime.Now;
      }
      context.SubmitChanges();

    In both cases, you're looking up the Employee on the client side. If this isn't practical, then a service operation might be your best option. Just make sure to run this.Context.Submit at the end of the operation to persist the changes.

    Kyle

    Friday, August 14, 2009 12:35 PM
  • kyle,

    thanks again.

    xaml code behind:

    Employee emp = context.Employees.???? don't see SingleOrDefault ???????

    after Employees. i see:

    Add
    Attach
    CanAdd
    CanEdit
    ... and so on. But no SingleOrDefault.

    any idea?

    Friday, August 14, 2009 1:14 PM
  • I see it in the domain service. The code you posted refer to the function(s) in the domain service and not the code behind the xaml file.

     

    thanks.

    Friday, August 14, 2009 1:22 PM
  • so here's my result:

    code behind from the xaml:

    context.UpdateEmployeeByID(100, "Completed", DataTime.Now);

    Domain Service:

    [ServiceOperation]
    public void UpdateEmployeeByID(int ID, string Status, DateTime dt)
    {
         Employee emp = this.context.employees.first(e => e.id == ID);
         if(emp != null)
         {
              e.status = Status;
              e.ShippedDate = dt;

              this.context.SaveChanges();
         }
    }

    and this works. Anything wrong with this? Thank you.

    Friday, August 14, 2009 1:56 PM

  • Employee emp = context.Employees.SingleOrDefault(e => e.id == 100);
      if (emp != null)
      {
        emp.UpdateStatus(1, DateTime.Now);
      }
      context.SubmitChanges();

    In the context of this http://silverlight.net/forums/t/119485.aspx issue: how do you handle this when the context has multiple Employee instances? You don't want other entities to be persisted to the database or even the custom operation not being invoked because another entity is invalid. Any thoughts?

    Friday, August 14, 2009 2:21 PM