关于使用ADO.Net数据服务,我应该知道些什么? (常问问题)

时间:2009-10-06 16:32:18

标签: c# silverlight linq-to-sql entity-framework wcf-data-services

在过去的几个月里,我一直在学习ADO.Net Data Services (Astoria),虽然我喜欢这项技术但学习却是一次真正的尝试。您需要有效使用它们的信息分布在MSDN文档,文章,博客文章,支持论坛以及StackOverflow上。这个问题是我分享一些来之不易的发现以便其他人可以受益的地方。我也希望其他人能够提供他们的最佳实践和常见问题解答,并纠正我的误解!

为了完全公开,我一直在使用Linq to SQL的框架只是为了让我的生活变得更复杂,所以我希望我的答案中的细节也适用于Entity Framework。

从下面开始,我发现一些必不可少的链接。然后我会在主题特定位中放置答案部分。

有用的链接

3 个答案:

答案 0 :(得分:2)

服务运营

有时能够查询数据并执行简单的更新或创建是不够的 - 您可能希望实现一些业务逻辑或一些通过URI方案无法实现的复杂查询创建。 Data Services以服务操作的基本形式支持此功能。

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

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

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

答案 1 :(得分:1)

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中生成:Introduction to Data Binding in Silverlight 3 with 1.5 CTP2

更新了服务器数据

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

myContext.MergeOption = MergeOption.OverwriteChanges

跨域访问

Silverlight为ADO.NET Data Services 1生成的类型使用自己的网络堆栈来提供更多请求谓词,但不幸的是,这意味着不应用跨域策略,也无法进行跨域请求。要解决此问题,您可以代理请求或等待支持Silverlight 3中的跨域的1.5版(当前可用的CTP 2)。

<强>链接:

答案 2 :(得分:1)

使用Linq to SQL

您可以使用Linq to SQL作为数据服务的只读数据上下文,开箱即用:

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 tip而不是Data Services特有的,但这是我使用Linq到Sql的唯一地方。要停止此行为,请进入Linq to Sql设计器并选择您不想检查的字段。将UpdateCheck属性更改为Never或OnlyWhenChanged。