Getting Started with ADO.NET Data Services and Telerik Open Access – Step II

Monday, December 15, 2008 by Dimitar Kapitanov | Comments 4

In my previous post we looked into providing data to the client using ADO.NET Data Services and Telerik OpenAccess. However it is very rare just to present data, as usually some processing is done by the application on the client side, data gets modified and it is pushed back to the server for persistence. With ADO.NET Data Services this is done by implementing the IUpdateable interface by the data context class used on the server.

NOTE: We do not implement IExpandProvider at the moment.

They say that a picture is worth a thousand words, so same is true for the code – I just present you the code required for updates:

#region IUpdatable Members

public object CreateResource(string containerName, string fullTypeName)
{
    Type t = Type.GetType(fullTypeName);
    Debug.Assert(t != null);  // assume can find type
    object resource = Activator.CreateInstance(t);
    Scope.Add(resource);
    return resource;
}

public object GetResource(IQueryable query, string fullTypeName)
{
    object resource = null;

    foreach (object o in query)
    {
        if (resource != null)
        {
            throw new Exception("Expected a single response");
        }
        resource = o;
    }

    if (resource == null)
        return new Exceptions.NoSuchObjectException("Object cannot be found.", null);

    if (fullTypeName != null && resource.GetType() != Type.GetType(fullTypeName))
        throw new Exception("Unexpected type for resource");

    return resource;
}

public object ResetResource(object resource)
{
    Debug.Assert(resource != null);
    Scope.Refresh(resource);
    return resource;
}

public void SetValue(object targetResource, string propertyName, object propertyValue)
{
    PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
    if (pi == null)
        throw new Exception("Can't find property");
    pi.SetValue(targetResource, propertyValue, null);
}

public object GetValue(object targetResource, string propertyName)
{
    PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
    if (pi == null)
        throw new Exception("Can't find property");
    return pi.GetValue(targetResource, null);
}

public void SetReference(object targetResource, string propertyName, object propertyValue)
{
    SetValue(targetResource, propertyName, propertyValue);
}

public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
    PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
    if (pi == null)
        throw new Exception("Can't find property");
    IList collection = (IList)pi.GetValue(targetResource, null);
    collection.Add(resourceToBeAdded);
}

public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
{
    PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);
    if (pi == null)
        throw new Exception("Can't find property");
    IList collection = (IList)pi.GetValue(targetResource, null);
    collection.Remove(resourceToBeRemoved);
}

public void DeleteResource(object targetResource)
{
    Scope.Remove(targetResource);
}

public void SaveChanges()
{
    Scope.Transaction.Commit();
}

public object ResolveResource(object resource)
{
    Scope.Retrieve(resource);
    return resource;
}

public void ClearChanges()
{
    Scope.Transaction.Rollback();
}

#endregion

 

Yes, this is just what you need to accomplish to have updates pushed back to the server in this example.

To see the service up and running make your web site the startup site and just hit F5. This will start the test web server and the service. Then open a browser and navigate to the service: "http://localhost:<port>/OADataServices/OADataService.svc"

 

image

 

Basically this is all about the server part of the application. In the next post I will guide you how to create extremely simple SilverLight test application that interacts with the provided service. Also I will try to implement the whole sample application in VB.NET as there is strong demand for that. Enjoy!

4 Comments

  • Ben Hayat 15 Dec
    Hi Dimitar;

    I have a question, which is really an educational question [for me] than anything else ;-)

    I'm always trying to find the best tools for my development which provides best quality and integration.
    Currently, I've chosen RadSilverlight as my main tool for Silverlight and I'm very happy with the product (and I think even better than the product, is the support)! I would also like to consider OpenAccess as my ORM for Astoria instead of the default ORM that Astoria supports out of the box (EF) .

    My question is, could you please point out what would be the advantage(s) of OA versus using EF or LinqToSQL? I think showing how to use the OA with Astoria, is great, but I think the first question that comes to mind, even Astoria team prefered EF over Ling2SQL for their ORM. I would like some good information why OA would be better for a NEW project?

    Thank you in advance!
    ..Ben
  • Kapitanov 19 Dec
    Hi Ben,
    First of all I suggest you should really take a look here: http://davidhayden.com/blog/dave/archive/2008/12/14/IUpdatableLINQToSQLADONETDataServicesUpdatedORMappers.aspx

    What we will provide in the first place is our commitment to drive the development of our O/R mapping tool towards providing the following:

    1. Advanced Visual Studio integration, UI wizards and guidance to allow almost coding-free experience for the most of frequently used scenarios.

    2. Superb runtime speed and productivity compared to other O/R mapping tools.

    3. Various bindings and support for generic WCF services, Ado.Net Data Services, possible integration with IoC frameworks popular in the market, and all that on all of the platforms that we intend to support: Asp.Net, Windows Forms, WPF and SilverLight. Of course it will take some time, but those are our intentions.

    4. Major improvement to API usability. We intend to provide complete support for LINQ, possibly develop "Fluent API" for our product, and last but not least develop a DSL on top of our runtime - just the way you have it with EF and L2S.

    All that said, you should take into account also the traditional things we value here: customer support, frequent releases and  all other qualities that make the Telerik brand. Do not hesitate to contact us further with any questions you might have.

  • Ben Hayat 19 Dec
    Hi Dimitar;
    I thank you for giving detail information about the roadmap. I had asked similar questions elsewhere about OA and I was left with no answer. So, I do appreciate your answers. The link you provided to David's blog was great. I had missed that.
    I'm in close contact with Valentin and he did mention that there is plan of integrating OA with SL and new products from Microsoft.
    I think the above statements should be echoed in the OA section for people to know why and how Telerik is planning to use OA.
    Thanks again!
    ..Ben
  • Ian Gregory 24 Apr
    Hi Dimitar,

    Thanks for a fantastic set of articles.

    I have been implementing the approach using a forward mapped database and came across a problem that has just taken a couple of hours to troubleshoot.

    I came across an error when I ran the service in IE - 

    The server encountered an error processing the request. See server logs for more details.

    It turns out that ADO.Net Data Services needs to know the primary key of the entity.  When the class is implemented in code (rather than the Entity metadata approach) it assumes that the key has 'ID' in its name.  However, since I had set up Open Access to use an Internal Key, the key was not in the class, hence the error.  Your products class has a primary key ProductID, so this problem did not occur.

    The explanation and solution can be found here in Marc Gravell's blog: http://marcgravell.blogspot.com/2008/12/astoria-and-linq-to-sql-getting-started.html - you have to add the DataKeyAttribute to the class.

    He doesn't mention that you have to reference System.Data.Services.Client assembly to get the attribute which is in System.Data.Services.Common.

    Hope this helps others to resolve the same issue

    Ian

Add comment

  1. Formatting options
       
     
     
     
     
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)