参考资料
【1】http://www.codeproject.com/KB/aspnet/SaltAndPepper.aspx?display=Print
【2】Manning LINQ in action
【3】ScottGu, LINQ to SQL, 2007
前言
有了LINQ之后,我发现开发ASP.NET网站的时候,编写数据库操作也成为了一件有意思的事情。为了更好在应用LINQ的过程中适应系统的N-Tier架构设计,需要进行一些研究。
简介
N-Tier架构其实可以用3-Tier架构来概括,分为Presentation Layer,Business Logic Layer和Data Access Layer。 LINQ to SQL is an ORM (object relational mapping) implementation that allows you to model a relational database using .NET classes.
Business Logic Layer的作用简要说来就是一个词:Shaping。
LINQ的问题
传统的3层架构Need to write business logic mapping from DAL data sources[1].70% projects in IT industry are CRUD projects. In 3-tier architecture the CRUD operation needs to transfer data to and from between layers. Due to inconsistent data representation between tiers the matter gets more complicated for CRUD operations[1]. LINQ提供了“a consistent data representation across all tiers and general query mechanism by which we can filter and sort business objects.”[1]。
业务层的功能主要是areas of performance,maintainability, and code reuse.[2] p8.3
但是在目前,LINQ最大的问题是如何跨多个表返回数据类型,以及UI数据字段名称与DB数据字段名称之间的映射(这样可以更好的解耦和数据库设计和ASPX页面代码)。因为在UI层需要大量不一样的数据显示。(把这个归入UI层?)
目前的解决办法是,在BO层的返回数据直接使用DAL的entity类,而在UI层的ASPX.VB代码中进行数据字段名称映射,这样可以让ASPX网页代码相对稳定,而且有能够通过LINQ的特性,在数据库改动时通过编译提示代码更新。
UI代码:
dropDownList.DataSource = From c In GetMaterialsAccessor.Filters(userid, containOthers) _
Select fnumber = c.FilterNumber, fname = c.FilterName
BO层代码:
Public Function Filters(ByVal ownerID As String, ByVal includeOthers As Boolean) As IQueryable(Of MaterialOutgoingFilter)
Dim a As New HillytonMaterialsDataContext
Dim query = From c In a.MaterialOutgoingFilters _
Where c.OwnerID = ownerID Select c
If includeOthers Then
Dim otherquery = From c In a.MaterialOutgoingFilters _
Where c.OwnerID <> ownerID And c.Private = 0 _
Select c
query = query.Concat(otherquery)
Else '仅包含系统管理员的公共过滤器
Dim others = From c In a.MaterialOutgoingFilters _
Where c.OwnerID <> ownerID And c.OwnerID = "0000" And c.Private = 0 _
Select c
query = query.Concat(others)
End If
Return query
End Function
这看来是一个比较可行的方法了,在这里,LINQ语句作为“Common Query Language[1]”在BO层和UI层发挥作用 。那么最基础的工作就是要设计好数据库表,这样通过LINQ自动生成的Entity类才能够易于使用。
那么现在看来,LINQ跨越多个表查询的时候,一个简单的并且与上述实现方式一致的实现方式也就是返回entity对象,通过数据库的主键、外键关联得到其它表的数据,在UI层使用LINQ进行跨表取数据。