linq2sql简单实践:Only CRUD
前一阶段楼猪很是忙碌了一阵,在一个小项目中已经开始使用linq2sql来开发了,但是晕晕乎乎好像没怎么深入就结束了,现在依然感觉意犹未尽。下面自己动手再重新实践简单学习一下linq2sql,加深自己的理解,对新手也许有用。
一、前期准备
1、开发环境:vs2010+sql server2005/2008
2、数据库TestDb:
GO
CREATE DATABASE [TestDb] ON PRIMARY
( NAME = N'TestDb', FILENAME = N'****\MSSQL\DATA\TestDb.mdf' , SIZE = 87040KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'TestDb_log', FILENAME = N'****\MSSQL\DATA\TestDb_log.ldf' , SIZE = 291904KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
COLLATE Chinese_PRC_CI_AS
GO
3、数据表Person:
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[LastName] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Weight] [float] NULL,
[Height] [float] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
二、LINQ To SQL项目实践
新建解决方案LinqApp:
1、DAL层的核心实现
添加LinqDAL类库,新建一个LINQ To SQL类TestDbPerson.dbml,在设计视图上选择TestDb的Person表,拖动到类设计视图上,然后一路next,TestDbPerson.dbml初步完成:
需要注意的是,Person表的主键Id我们设计成自增长的int型,所以,插入的时候我们通常都会返回最新的id,这样,我们需要在dbml设计视图上修改Id的属性自动生成的主键设置为True(倒数第二行,默认为False):
有了这个设置,插入新纪录时,Id就可以自动返回了。
ps:上面生成的TestDbPersonDataContext类我们可以单纯理解它就是微软为我们封装的一个针对数据库TestDb的通用数据访问对象(dao),通过这个dao,我们可以进行对应数据表的增删改查等常用操作。按照楼猪使用iBatisNet的经验,也模仿一下常用数据访问层的编写:
上图中,在Implement文件夹内,BaseService类包含了创建对外调用数据访问服务的单例方法,以及一个获取查询对象sql语句(形如@param1,@param2...的参数化后的sql语句)的泛型方法:
using System.Linq;
using System;
namespace LinqDAL
{
public abstract class BaseService<T> where T : class, new()
{
private static readonly object syncRoot = new object();
private static T Instance = null;
/// <summary>
/// 单例模式
/// </summary>
/// <returns></returns>
public static T GetInstance()
{
if (Instance == null)
{
lock (syncRoot)
{
if (Instance == null)
{
Instance = new T();
}
}
}
return Instance;
}
/// <summary>
/// 获取select时的sql语句
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="dataContext"></param>
/// <param name="query"></param>
/// <returns></returns>
public string GetSelectSql<TSource>(DataContext dataContext, IQueryable<TSource> query)
{
string sql = null;
try
{
sql = dataContext.GetCommand(query).CommandText;//获得生成的sql语句
}
catch (Exception ex)
{
sql = string.Format("获取sql出现异常:{0}", ex.Message);
}
return sql;
}
}
}
关于获取linq2sql生成的sql语句的方法,博客园已经有几篇文章讲解很详实,楼猪就不多做介绍了。在最后给出的demo中,查询数据集的时候,楼猪调用基类里的GetSelectSql泛型方法,增删改的时候,则是通过最简单的DataContext的Log属性。其实不通过上面编程的方法也可以查看生成的sql语句。直接通过vs2010强大的IntelliTrace(打开vs2010,选择“工具”选项卡,找到IntelliTrace,选择“启用IntelliTrace”,在“IntelliTrace事件”中可以看到默认已经选择了ADO.NET),我们也可以看到对应的sql语句,如果您是个有心人,也许还会联想到更多linq2sql的底层实现的小秘密,截张图给大家看看,您可以在自己的机器上试一试:
仔细观察一下上面这张图,看出什么“猫腻”了吗?熟练使用ado.net或者iBatis.net或者其他ORM编程的朋友估计已经笑而不语了:sql语句都给我们生成了,主要使用了什么ado.net对象(这里显示是一个SqlDataReader对象,应该还有一个SqlConnection对象没有提示我们,当然即使告诉我们,我们也不关心)也给我们提示了(linq2sql数据访问的本质是ado.net的再次封装,此言诚不我欺也。^_^,“小样,别以为穿了马甲我就不认识你了”),MS真是懂我们啊。以后的开发中,我们跟踪调试sql语句的工作都可以省了。
2、表现层的调用
新建一个控制台应用程序LinqApp,CRUD一个一个测试一遍:
using System.Collections.Generic;
namespace LinqApp
{
using LinqDAL;
using LinqDAL.Dao;
class Program
{
static void Main(string[] args)
{
Person model = new Person();
model.FirstName = "jeffery";
model.LastName = "zhao";
model.Height = 185;
model.Weight = 80;
int id = ServiceFactory.CreatePersonService().AddPerson(model);//添加
IList<Person> listPersons = ServiceFactory.CreatePersonService().GetPagerPersons(1, 1);//取出第一页 每页10条记录
model = new Person();
model.Id = id;
model.FirstName = "jeff";
model.LastName = "wong";
model.Height = 176;
model.Weight = 60;
ServiceFactory.CreatePersonService().ModifyPerson(model);//更新
listPersons = ServiceFactory.CreatePersonService().GetPagerPersons(1, 1);//取出第一页 每页10条记录
ServiceFactory.CreatePersonService().RemovePerson(id);//删除
Console.Read();
}
}
}
您可以自己尝试一下。总体来说,对于常用的CRUD操作,开发人员自己控制的很少(福兮?祸兮?),linq2sql都给我们做好了,使用起来非常快捷方便。
demo下载:demo
作者:Jeff Wong
出处:http://jeffwongishandsome.cnblogs.com/
本文版权归作者和博客园共有,欢迎围观转载。转载时请您务必在文章明显位置给出原文链接,谢谢您的合作。