zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    进程池Pool
    进程间通信-Queue
    多任务版udp聊天器
    列表循环放引用并写出打印结果
    协程实现tcp两个客户端的通讯
    正则匹配身份证和邮箱
    python中上双互斥锁的线程执行流程
    小巧的http live streaming m3u8播放器
    js实现@提到好友
    mongoose多级嵌套操作
  • 原文地址:https://www.cnblogs.com/jeffwongishandsome/p/1784606.html
Copyright © 2011-2022 走看看