关于使用 ADO.Net 数据服务,我应该了解哪些信息? (常问问题)

发布于 2024-08-07 01:48:43 字数 1057 浏览 6 评论 0原文

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神回复 2024-08-14 01:48:43

服务操作

有时,能够查询数据并执行简单的更新或创建是不够的 - 您可能想要实现一些业务逻辑或一些复杂的查询创建,而这是通过 URI 方案无法实现的。数据服务通过服务操作以非常基本的形式支持这一点。

这些允许您向服务添加方法,但有一些限制:

  1. 您只能使用基本类型或实体类型(即服务已公开的类型)。
  2. 方法参数只能是可以表示为 URL 一部分的简单类型。
  3. datasvcutil 不会为服务操作生成任何代码,因此您需要自己将它们添加到客户端库中。
  4. 如果您返回实体类型但没有任何内容可返回,即结果为 null,那么您将得到 404 作为 HTTP 响应。
  5. 如果返回 void,您将无法使用客户端数据上下文来发出请求,您必须使用 WebRequest。

示例(好吧,这些都是简化的,所以实际上不需要服务操作):

[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);
}

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);
}
殊姿 2024-08-14 01:48:43

Silverlight 客户端库

LINQ 查询

乍一看,linq 语法似乎无法在您的上下文中使用,因为所有查询都是异步的,并且 IEnumerable 显然没有 BeginExecute 方法。要使用 Linq 语法,您需要转换最终查询:

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

请注意,查询是传入的,这是因为您需要使用相同的 DataServiceQuery 实例来调用 EndExecute,您不能只使用上下文。

更改跟踪

客户端库不会自动跟踪生成类型中的字段更改。为此,您必须在部分类型中实现 INotifyPropertyChanged。

示例:

public partial class Product : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;

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

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

在 1.5 版中,数据服务工具可以为您生成此内容,但目前仅在 CTP 中:Silverlight 3 中的数据绑定简介(1.5 CTP2)

更新的服务器数据

默认情况下,Silverlight 客户端上下文设置了 MergeOption仅追加。这意味着,一旦您第一次查询实体,您将不会看到实体的任何更改,这是一种缓存和性能优化的形式。要查看更新,您需要将 MergeOption 更改为 OverwriteChanges,这将确保对象得到更新。您也可以丢弃您的上下文并重新创建。

myContext.MergeOption = MergeOption.OverwriteChanges

跨域访问

Silverlight 为 ADO.NET 数据服务 1 生成的类型使用自己的网络堆栈来提供更多请求谓词,但不幸的是,这意味着未应用跨域策略,并且您无法发出跨域请求。 它支持 Silverlight 3 中的跨域。

要解决此问题,

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:

素年丶 2024-08-14 01:48:43

使用 Linq to SQL

您可以立即使用 Linq to SQL 作为 Data Services 的只读数据上下文:

public class MyService : DataService<MyLinqToSqlDataContext>

但是,要获得更新/写入支持,您需要为 Linq to SQL 实现 IUpdateable 。幸运的是,Andrew Conrad 在 MSDN 代码库中为您提供了一个:

ADO.Net Data Services IUpdateable implementation for Linq to Sql

将其作为数据上下文的分部类放入,您就可以进行写入和读取了。请注意,此实现确实存在网站上详细介绍的一些小问题,并且有时按设计将数据服务与实体框架一起使用感觉更加无缝。

更新检查

存储更改时,您将看到 Linq to Sql 生成一个 WHERE 子句来检查字段上的现有值,但这并不总是您想要的。这实际上是一个 Linq to Sql 技巧,而不是特定于数据服务,但这是我使用 Linq to Sql 的唯一地方。要停止此行为,请进入 Linq to Sql 设计器并选择您不想检查的字段。将 UpdateCheck 属性更改为 Never 或 OnlyWhenChanged。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文