如何在ASP.NET项目里面正确使用Linq to Sql

非常抱歉,由于需要发表其他文章的缘故,我只能忍着不修正文中一小部分错误,以及增加一些有助免于误解的内容。这里特别说明一下,本文不是要讨论缓存机制的好坏,更不是要讨论如何缓存对象。而是说DAL/BLL上面对DataContext的处理。另外一个需要注意的地方,是修改了一个错误,原来大部分都写成IQueryable了,实际上应该是除了最后一个之外,都是IEnumerable。原因是什么需要大家想一下。此外,也需要大家注意的事,我所提出来的缓存,并不是直接利用Linq2Sql的代码来缓存,而是指是否便于缓存。这部分的内容,会在文章后面补充说明。

Linq to Sql 用的人也应该有些吧,我在cnblogs上面看老赵写的那几篇文章(请看08年9月左右的文章),感觉也很有深度,有不少启发。因此我也打算写一点我自己的实践经验,希望也能同样给大家一些有用的启发吧。

我首先想要问一下大家,Linq to Sql有哪些很特别的地方?这个问题的答案肯定五花八门,我说一下我看到的一些问题吧。

首先,Linq to Sql的基础之一是DataContext,而另外一个基础,则是通过映射产生的实体类,以及这些实体类的Table<>对象。这个不是废话嘛!我想很多人都应该知道这个最基本的知识,不过却不见得有多少人真正注意到,或者认真思考一下这里面的“机关”。不知道“机关”在哪里,那么就不可能写出合适的代码。比如说,在某个页面里面(N层结构没有给弄好的情况下),或者在某个业务逻辑里面(有N层结构),你的Linq to Sql的代码是否是长这样的?

using (MyDataContext db = new MyDataContext)
{
  var q = from product in db.ProductInfos
          where product.Price > 100
          select product;
  DoSomethingWithProducts(q.ToList());
}

“对啊,就是长这样的,有什么问题吗?”当然有问题啦,否则我也不写这个随笔了。不知道大家有没有想过这么一个问题,什么叫做Context?Context就是上下文,上下文的意思就是,依赖于这个上下文的对象,必须存活在这个上下文里面。脱离了这个上下文,那些对象就会出现错误。事实上也确实如此:在上面的例子里面,从ProductInfos中得到的q.ToList(),里面的每一个元素都依赖于MyDataContext。换句话说MyDataContext如果被注销了,q.ToList()生成的对象也就会“部分功能失效”。

“失效就失效好了,反正该做的工作已经做完了,q.ToList()也已经利用完了。”不错,在上面的例子里面,不会发生什么错误。不过这么写的话,会比较难使用的。为什么这么说?我举一个具体的例子:这个网站需要用户登录,而所有的业务逻辑几乎都依赖于当前用户。如果说,我们使用上面的using模式,那么我估计你的代码不外乎是如下两种情况:

1、每一次需要当前用户的地方,你都需要从数据库读取;或者

2、你把当前用户保存为全局变量了,但是你发现currentUser.CompanyInfo因为上下文已经抛弃了,因此是无法使用的,业务层不得不每一次都重新从数据库读取该用户所属公司的数据。

这两种形式如下所示:

// 通过实体对象来存储
// 注意!这个函数是不在BLL层的,而是更上层的某些处理,为了演示起来简单,显得是BLL层的东西。
public double GetCurrentBalanceByObject()
{
   int userId;
   int.TryParse(HttpContext.Current.User.Identity, out userId);
   UserInfo user = GetUser(userId);
   CompanyInfo company = GetCompanyByUser(user);
   IEnumerable<TransactionInfo> transactions = GetTransactionsByCompany(company);
   return transactions.Sum(item => item.Amount);
}

// 后面这几个方法才是BLL层的东西,后面的例子也相同。
public UserInfo GetUser(int userId)
{
   using(MyDataContext context = new MyDataContext)
   {
      return context.UserInfos.Where(item => item.UserId == userId).FirstOrDefault();
   }
}

public CompanyInfo GetCompanyByUser(UserInfo user)
{
   using(MyDataContext context = new MyDataContext)
   {
      return context.CompanyInfos.Where(item => item.UserId == user.Id).FirstOrDefault();
   }
}

public IEnumerable<Transaction> GetTransactionsByCompany(CompanyInfo company)
{
   using(MyDataContext context = new MyDataContext)
   {
      return context.TransactionInfos.Where(item => item.CompnayId == company.Id).ToList;
   }
}

// 实际上很容易就退化为通过键值来存储,因为在这种设计方式下面,
// 实际上根本没有什么必要去传输整个对象。
// 我们可以想象,这个时候很多的操作其实是依赖UserId和CompanyId的,
// 而我见过的“有趣”设计,是在Page_Load事件中,不管是否需要用到,
// 都会将HttpContext.Current.User.Identity以及
// GetCompanyByUserId(userId).CompanyId保存为当前页面的全局变量。
// 其实这样是违背了Linq的设计初衷的。
// 当然,我不是说不缓存最经常用的东西,该缓存还是要缓存的,只是,
// 下面的设计只会把问题变复杂。因为这里只能缓存一个id值,内部还是要重复获取User或者Company对象的。
// 下面就是一个只传Id的做法:
public double GetCurrentBalanceByObject()
{
   int userId;
   int.TryParse(HttpContext.Current.User.Identity, out userId);
   CompanyInfo company = GetCompanyByUserId(userId);
   IEnumerable<TransactionInfo> transactions = GetTransactionsByCompanyId(company.CompanyId);
   return transactions.Sum(item => item.Amount);
}

public CompanyInfo GetCompanyByUser(int userId)
{
   using(MyDataContext context = new MyDataContext)
   {
      return context.CompanyInfos.Where(item => item.UserId == userId).FirstOrDefault();
   }
}

public IEnumerable<Transaction> GetTransactionsByCompanyId(int companyId)
{
   using(MyDataContext context = new MyDataContext)
   {
      return context.TransactionInfos.Where(item => item.CompnayId == companyId).ToList();
   }
}

时间: 2024-11-03 03:35:48

如何在ASP.NET项目里面正确使用Linq to Sql的相关文章

艾伟:如何在ASP.NET项目里面正确使用Linq to Sql

老久不上来写技术类的东西了,偶尔回归一下吧.(其实,这篇文章8个月前写了个大半,后来一直没有时间去完善,再后来就因为各种原因给放下来了.) Linq to Sql 用的人也应该有些吧,我在cnblogs上面看老赵写的那几篇文章(请看08年9月左右的文章),感觉也很有深度,有不少启发.因此我也打算写一点我自己的实践经验,希望也能同样给大家一些有用的启发吧. 我首先想要问一下大家,Linq to Sql有哪些很特别的地方?这个问题的答案肯定五花八门,我说一下我看到的一些问题吧. 首先,Linq to

一起谈.NET技术,【译】ASP.NET MVC并不仅仅只是Linq to SQL

很多ASP.NET的教程中的示例代码使用的数据访问方法是Linq to Sql或是Entity Framework.我在www.asp.net的论坛上看到很多关于讨论是否有其他替代的数据库访问方式,回答是:当然有.这篇文章就讲述了使用Ado.Net作为数据访问层来实现一个典型的增删查改程序. 由于是以练习作为目的,那我就不妨借用Spaanjaar's 的N层构架文章(Building Layered Web Applications with Microsoft ASP.NET 2.0.)的构架

Asp.net MVC并不仅仅只是Linq to SQL

很多Asp.net的教程中的示例代码使用的数据访问方法是Linq to Sql或是Entity Framework.我在 www.asp.net的论坛上看到很多关于讨论是否有其他替代的数据库访问方式,回答是:当然有.这篇文章 就讲述了使用Ado.Net作为数据访问层来实现一个典型的增删查改程序. 由于是以练习作为目的,那我就不妨借用Spaanjaar's 的N层构架文章(Building Layered Web Applications with Microsoft ASP.NET 2.0.)的

【译】ASP.NET MVC并不仅仅只是Linq to SQL

很多ASP.NET的教程中的示例代码使用的数据访问方法是Linq to Sql或是Entity Framework.我在www.asp.net的论坛上看到很多关于讨论是否有其他替代的数据库访问方式,回答是:当然有.这篇文章就讲述了使用Ado.Net作为数据访问层来实现一个典型的增删查改程序. 由于是以练习作为目的,那我就不妨借用Spaanjaar's 的N层构架文章(Building Layered Web Applications with Microsoft ASP.NET 2.0.)的构架

实例学习如何在ASP中调用DLL

本文通过VB5.0创建ActiveX DLL文件,这个文件模拟了一个掷色子的过程,向大家介绍如何在ASP中调用DLL的文章专题. 动态联接库(DLL)是加快应用程序关键部分的执行速度的重要方法,但有一点恐怕大部分人都不知道,那就是在ASP文件也能通过调用DLL来加快服务器的执行速度,下面我简单的介绍一下在ASP文件调用DLL的步骤.  首先,必须得有DLL文件,本例是通过VB5.0创建ActiveX DLL文件,这个文件模拟了一个掷色子的过程.  在VB5.0的环境下,新建一个工程,并双击新建工

以前收集的一些资料---如何在ASP中通过ODBC调用Excel中的数据

excel|odbc|数据                如何在ASP中通过ODBC调用Excel中的数据    在ASP中通过ODBC调用Excel中的数据方式和普通的通过ODBC调用数据库的方式有一些不同的地方.下面将介绍如何通过ODBC在ASP中使用Excel的数据.    在使用的过程中,要注意的是你需要使用的ODBC驱动为:Microsoft ODBC Driver for Excel. 下面给出一个例子来具体说明如何调用的过程:1.在Excel的电子表格中新建一个叫Range的表单a

如何在asp.net保护文件

asp.net 如何在asp.net保护文件 简介如果我们做网站是用Access数据库作为数据源,则我们最关心的是Access数据库文件的安全问题.如果我们将存有重要信息(如密码.付款信息.个人私有的数据等等)的.mdb文件,放在Web服务器上可访问的目录中,任何一个人若猜到数据库文件名就可以通过浏览器或其他下载工具进行下载,这是非常危险的. 有许多方法对.mdb数据库文件进行保护,甚至任何一个你想保护的文件.最直接有效的方法是把.mdb数据库文件放在web服务器non-web accessib

如何在ASP.NET中用OWC绘制图表(1)

asp.net|图表 如何在ASP.NET中用OWC绘制图表 (1) 一.概述 二.设置图表引擎 三.OWC的许可证问题 四.OWC的运行机制 五.在Web服务器上安装OWC 10 六.OWC编程模式 ━━━━━━━━━━━━━ 正文: ━━━━━━━━━━━━━ 一.概述 在开发应用程序时,经常会遇到必须提供交互式图表的情况.例如,你可能在开发一个管理销售和产品数据的应用程序,数据保存在SQL Server数据库上,应用程序允许用户添加数据.更新现有数据,但除了这些功能之外,客户还要求应用程序

项目开发经验-ASP.NET项目开发中的异常处理

前言:异常的处理在项目开发中是很有必要的,异常的处理不仅仅只是try..catch..finally就完事了的.异常处理绝对可以称开发中的重要组成部分.必须正确的面对异常,因为即使是最能干的开发人员,也要面对这个问题 .... 我们不知道客户是怎么样使用我们开发的软件的,所以我们必须处理这样的情况:如果系统不按照我们的设计时所想的运行,我们改怎么办? 下面我们就来具体的介绍在ASP.NET项目开发中的异常的处理方式,希望看完后,大家可以回答上面的问题. 本篇的话题如下: 应用程序级别异常处理的错