具有 Web 服务的 LINQ to SQL N 层

LINQ to SQL 专为在松散耦合的数据访问层(DAL)(如 Web 服务)的中间层上使用而设计。 如果呈现层是 ASP.NET 网页,则使用 LinqDataSource Web 服务器控件管理用户界面与中间层 LINQ to SQL 之间的数据传输。 如果演示文稿层不是 ASP.NET 页,则中间层和演示层必须执行一些额外的工作来管理数据的序列化和反序列化。

在中间层配置 LINQ to SQL

在 Web 服务或 n 层应用程序中,中间层包含数据上下文和实体类。 可以手动创建这些类,也可以使用 SQLMetal.exe 或对象关系设计器,如文档中的其他地方所述。 在设计时,可以选择使实体类可序列化。 有关详细信息,请参阅 “如何:使实体可序列化”。 另一种方法是创建一组单独的类,用于封装要序列化的数据,然后在 LINQ 查询中返回数据时投影到这些可序列化类型中。

然后,使用客户端将调用的方法定义接口,以检索、插入和更新数据。 接口方法用于封装你的 LINQ 查询。 可以使用任何类型的序列化机制来处理远程方法调用和数据序列化。 唯一的要求是,如果在对象模型中具有循环或双向关系,例如标准 Northwind 对象模型中的 Customers 和 Orders 之间,则必须使用支持它的序列化程序。 Windows Communication Foundation (WCF) DataContractSerializer 支持双向关系,但与非 WCF Web 服务一起使用的 XmlSerializer 不支持。 如果选择使用 XmlSerializer,则必须确保对象模型没有循环关系。

有关 Windows Communication Foundation 的详细信息,请参阅 Visual Studio 中的 Windows Communication Foundation 服务和 WCF 数据服务

使用 DataContext 和实体类上的分部类和方法接入 LINQ to SQL 运行时事件,以实现您的业务规则或其他特定于域的逻辑。 有关详细信息,请参阅 实现 N 层业务逻辑

定义可序列化类型

客户端或表示层必须具有从中间层接收的类的类型定义。 这些类型可能为实体类本身,或是仅包装实体类中的特定字段以进行远程处理的特殊类。 在任何情况下,LINQ to SQL 都完全不关心呈现层如何获取这些类型定义。 例如,呈现层可以使用 WCF 自动生成类型,也可以具有在其中定义这些类型的 DLL 的副本,也可以只定义其自己的类型版本。

检索和插入数据

中间层定义一个接口,该接口指定呈现层如何访问数据。 例如 GetProductByID(int productID)GetCustomers()。 在中间层上,方法正文通常创建一个新实例 DataContext,对一个或多个表执行查询。 然后,中间层以结果IEnumerable<T>返回,T要么是实体类,要么是用于序列化的其他类型。 呈现层从不直接向中间层发送或接收查询变量。 这两个层交换具体数据的值、对象和集合。 收到集合后,表示层可以使用 LINQ to Objects 查询它(如有必要)。

插入数据时,呈现层可以构造一个新对象并将其发送到中间层,也可以让中间层根据它提供的值构造对象。 通常,在 n 层应用程序中检索和插入数据与 2 层应用程序中的过程没有什么不同。 有关详细信息,请参阅 查询数据库提交数据更改

跟踪更新和删除的更改

LINQ to SQL 支持基于时间戳(也称为 RowVersion)和基于原始值的乐观并发。 如果数据库表具有时间戳,那么更新和删除在中间层或表示层所需的额外工作很少。 但是,如果必须使用原始值进行开放式并发检查,则表示层在其进行更新时负责跟踪这些值并将这些值发送回去。 这是因为在表示层上对实体所做的更改不会在中间层上进行跟踪。 事实上,实体的原始检索和最终更新通常由两个完全独立的实例 DataContext执行。

呈现层所做的更改越多,跟踪这些更改并将其打包回中间层就越复杂。 通信更改机制的实现完全由应用程序决定。 唯一的要求是,必须向 LINQ to SQL 提供乐观并发检查所需的原始值。

有关详细信息,请参阅 N 层应用程序中的数据检索和 CUD 操作(LINQ to SQL)。

另请参阅