开发者

What should I know about working with ADO.Net Data Services? (FAQ)

I've been learning by doing with ADO.Net Data Services (Astoria) for the last couple of months, and while I like the technology the learning has been a real trial. Information that you 开发者_运维知识库need to use them effectively is spread over MSDN documentation, articles, blog posts, support forums and of course StackOverflow. This question is a place for me to share some of my hard-won findings so that someone else can benefit. I also hope for other people to contribute their best practices and FAQs, and correct my misunderstandings!

For full disclosure, I've been using the framework with Linq to SQL just to make my life more complicated, so I hope the details in my answers are appropriate for Entity Framework too.

To start with below are some links I've found essential. I'll then put topic specific bits in the answers section.

Useful Links

  • Data Services Home Page
  • Using Data Services article on MSDN
  • Data Services Support Forum
  • Data Services Team Blog
  • Tips For Using Silverlight 2 with ADO.NET Data Services


Service Operations

Sometimes being able to query data and perform simple updates or creations isn't enough - you might want to implement some business logic or some complex query creation that's not possible through the URI scheme. Data Services supports this in a very basic form with Service Operations.

These allow you to add methods to your service, but with some restrictions:

  1. You can only use basic types or entity types (i.e. types already exposed by the service).
  2. Method parameters can only be simple types that can be expressed as part of a URL.
  3. No code is generated for Service Operations by datasvcutil, so you need to add them to the client libraries yourself.
  4. If you return a entity type but don't have anything to return, i.e. the result is null, then you'll get a 404 as the HTTP response.
  5. If you return void you won't be able to use the client data context to make the request, you'll have to use WebRequest.

Examples (ok, these are simplified so don't really need to be Service Operations):

[WebGet]
public Product GetProductByID(int productID)
{
    return this.CurrentDataSource.Products.First(p => p.ID == productID);
}

[WebGet]
public IEnumerable<Product> GetCancelledProducts(int productID)
{
    return this.CurrentDataSource.Products.Where(p.Cancelled);
}


Silverlight Client Library

LINQ Querying

At first it looks like the linq syntax can't be used from your context, because all queries are asynchronous and IEnumerable obviously doesn't have a BeginExecute method. To use the Linq syntax you need to cast your eventual query:

var query = (DataServiceQuery<Product>)myContext.Products.Where(p => p.SupplierID == 5);
query.BeginExecute(this.HandleQueryResults, query);

Note the query is passed in, this is because you'll need to use the same DataServiceQuery instance to call EndExecute, you can't just use the context.

Change Tracking

The client library doesn't track field changes automatically in the generated types. For this to work you must implement INotifyPropertyChanged in your partial types.

Example:

public partial class Product : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;

    partial void OnProductIDChanged() { FirePropertyChanged("ProductID"); }
    partial void OnProductNameChanged() { FirePropertyChanged("ProductName"); }

    private void FirePropertyChanged(string property) { ... }
}

In version 1.5 the Data Services tooling can generate this for you, but it's currently only in CTP: Introduction to Data Binding in Silverlight 3 with 1.5 CTP2

Updated Server Data

By default the Silverlight client context has MergeOption set to AppendOnly. What this means is that you won't see any changes to entities once you've queried them for the first time, it's a form of caching and performance optimization. To see updates you need to change the MergeOption to OverwriteChanges, this will ensure the objects are updated. You can also throw away your context and re-create.

myContext.MergeOption = MergeOption.OverwriteChanges

Cross Domain Access

The Silverlight generated types for ADO.NET Data Services 1 use their own network stack to make more request verbs available, but unfortunately this means that the cross-domain policies are not applied and you can't make cross-domain requests. To work around this you can either proxy the requests or wait for version 1.5 (CTP 2 currently available) which supports cross-domain in Silverlight 3.

Links:

  • Creating an ADO.NET Data Service Proxy
  • Using the ADO.NET Data Services 1.5 CTP 2 Silverlight client in x-domain and out of browser scenarios


Working with Linq to SQL

You can use Linq to SQL as a read-only data context for Data Services right out of the box:

public class MyService : DataService<MyLinqToSqlDataContext>

To get update/write support, however, you'll need to have an implementation of IUpdateable for Linq to SQL. Fortunately Andrew Conrad has one up on the MSDN Code Gallery for you:

ADO.Net Data Services IUpdateable implementation for Linq to Sql

Drop this in as a partial class for your data context and you are ready to write as well as read. Do note that this implementation does have a few minor issues detailed on the site, and that sometimes using Data Services with Entity Framework as designed feels a little more seamless.

Update Checks

When storing changes you'll see that Linq to Sql generates a WHERE clause that checks the existing values on fields, which isn't always what you want. This is really a Linq to Sql tip rather than Data Services specific, but this is the only place I use Linq to Sql. To stop this behaviour go into the Linq to Sql designer and select the fields you don't want to check. Change the UpdateCheck property to Never or OnlyWhenChanged.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜