反射提供程序(WCF 数据服务)
除通过实体框架公开数据模型中的数据以外,WCF 数据服务 还可以公开未在基于实体的模型中严格定义的数据。 反射提供程序公开类中的数据,这些类返回实现 IQueryable<T> 接口的类型。 WCF 数据服务 使用反射推断这些类的数据模型,并且可以将针对资源的基于地址的查询转换为针对已公开 IQueryable<T> 类型的基于语言集成查询 (LINQ) 的查询。
备注
可使用 AsQueryable 方法从实现 IEnumerable<T> 接口的任何类返回 IQueryable<T> 接口。这允许将大多数泛型集合类型用作数据服务的数据源。
反射提供程序支持类型层次结构。 有关更多信息,请参见如何:使用反射提供程序创建数据服务(WCF 数据服务)。
推断数据模型
创建数据服务时,提供程序通过使用反射来推断数据模型。 以下列表显示了反射提供程序如何推断数据模型:
实体容器 – 将数据作为可返回 IQueryable<T> 实例的属性公开的类。 对基于反射的数据模型进行寻址时,实体容器表示服务的根。 对给定命名空间仅支持一个实体容器类。
实体集 – 返回 IQueryable<T> 实例的属性视为实体集。 在查询中,将把实体集作为资源直接进行寻址。 实体容器中只有一个属性才能返回给定类型的 IQueryable<T> 实例。
实体类型 – 实体集返回的 IQueryable<T> 的类型 T。 反射提供程序将作为继承层次结构一部分的类转换为等效的实体类型层次结构。
实体键 – 作为实体类型的每个数据类必须具有一个键属性。 该属性具有 DataServiceKeyAttribute 特性 ([DataServiceKeyAttribute])。
备注
您应将 DataServiceKeyAttribute 特性仅应用于可以用来唯一标识实体类型的实例的属性。当应用于导航属性时忽略此特性。
实体类型属性 – 与实体键不同的是,反射提供程序按如下方式处理作为实体类型的类的可访问非索引器属性:
如果属性返回基元类型,则假定该属性为实体类型的属性。
如果属性返回的类型同时也是实体类型,则假定该属性为导航属性,表示多对一或一对一关系的“一”端。
如果属性返回实体类型的 IEnumerable<T>,则假定该属性为导航属性,表示一对多或多对多关系的“多”端。
如果属性的返回类型为一个值类型,则该属性表示一个复杂类型。
备注
与基于实体关系模型的数据模型不同,基于反射提供程序的模型不了解关系数据。应当使用实体框架通过 WCF 数据服务 来公开关系数据。
数据类型映射
根据 .NET Framework 类推断数据模型时,数据模型中的基元类型按如下方式映射到 .NET Framework 数据类型:
.NET Framework 数据类型 |
数据模型类型 |
---|---|
Byte[] |
Edm.Binary |
Edm.Boolean |
|
Edm.Byte |
|
Edm.DateTime |
|
Edm.Decimal |
|
Edm.Double |
|
Edm.Guid |
|
Edm.Int16 |
|
Edm.Int32 |
|
Edm.Int64 |
|
Edm.SByte |
|
Edm.Single |
|
Edm.String |
备注
.NET Framework 可以为 null 的值类型会映射到与不能分配 null 的相应值类型相同的数据模型类型。
在数据模型中启用更新
为了对通过此类数据模型公开的数据进行更新,反射提供程序定义了一个 IUpdatable 接口。 该接口指示数据服务如何保持对公开类型的更新。 若要启用对数据模型定义的资源的更新,实体容器类必须实现 IUpdatable 接口。 有关 IUpdatable 接口的实现示例,请参见如何:使用 LINQ to SQL 数据源创建数据服务(WCF 数据服务)。
IUpdatable 接口要求实现以下成员,以便可使用反射提供程序将更新传播到数据源:
成员 |
说明 |
---|---|
提供将对象添加到从导航属性访问的相关对象集合的功能。 |
|
提供取消挂起的数据更改的功能。 |
|
提供在指定容器中创建新资源的功能。 |
|
提供删除资源的功能。 |
|
提供检索由特定查询和类型名称标识的资源的功能。 |
|
提供返回资源的属性值的功能。 |
|
提供从通过导航属性访问的相关对象集合中移除某一对象的功能。 |
|
提供更新指定资源的功能。 |
|
提供返回由特定对象实例表示的资源的功能。 |
|
提供保存挂起的所有更改的功能。 |
|
提供通过使用导航属性来设置相关对象引用的功能。 |
|
提供设置资源的属性值的功能。 |
处理并发
WCF 数据服务支持开放式并发模型,使您能够为实体定义并发标记。 这样一个包含一个或多个实体属性的并发标记由数据服务用来确定,正在请求、更新或删除的数据中是否发生了更改。 如果从请求的 eTag 中获取的标记值与实体的当前值不相同,则数据服务将引发异常。 将 ETagAttribute 应用于某个实体类型可在反射提供程序中定义并发标记。 并发标记不能包含键属性或导航属性。 有关更多信息,请参见更新数据服务(WCF 数据服务)。
配合使用 LINQ to SQL 和反射提供程序
由于默认情况下在本机支持实体框架,因此在结合使用关系数据和 WCF 数据服务时推荐使用此数据提供程序。 但是,可以使用反射提供程序来结合使用 LINQ to SQL 类和数据服务。 LINQ to SQL 对象关系设计器(O/R 设计器)生成的 DataContext 中的方法所返回的 Table<TEntity> 结果集实现 IQueryable<T> 接口。 这样,反射提供程序便可以通过使用生成的 LINQ to SQL 类从 SQL Server 访问这些方法和返回实体数据。 但是,由于 LINQ to SQL 不会实现 IUpdatable 接口,因此需要添加一个可扩展现有 DataContext 分部类的分部类才能添加 IUpdatable 实现。 有关更多信息,请参见如何:使用 LINQ to SQL 数据源创建数据服务(WCF 数据服务)。