linq2sql简单实践:Only CRUD

前一阶段楼猪很是忙碌了一阵,在一个小项目中已经开始使用linq2sql来开发了,但是晕晕乎乎好像没怎么深入就结束了,现在依然感觉意犹未尽。下面自己动手再重新实践简单学习一下linq2sql,加深自己的理解,对新手也许有用。

一、前期准备
1、开发环境:vs2010+sql server2005/2008
2、数据库TestDb:

USE [master]
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:

USE [TestDb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person](
    
[Id] [int] IDENTITY(1,1NOT 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.Data.Linq;
using System.Linq;
using System;

namespace LinqDAL
{
    
public abstract class BaseService<T> where T : classnew()
    {
        
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;
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(11);//取出第一页 每页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(11);//取出第一页 每页10条记录
            
            ServiceFactory.CreatePersonService().RemovePerson(id);
//删除

            Console.Read();
        }
    }
}

 您可以自己尝试一下。总体来说,对于常用的CRUD操作,开发人员自己控制的很少(福兮?祸兮?),linq2sql都给我们做好了,使用起来非常快捷方便。

demo下载:demo

posted on 2010-07-25 14:05  JeffWong  阅读(1966)  评论(2编辑  收藏  举报