linq to sql 扩展方法

老赵的博客:http://blog.zhaojie.me/2008/02/using-translate-method-and-modify-command-text-before-query-in-linq-to-sql.html

http://www.csharpwin.com/dotnetspace/9639r2943_2.shtml

1、DataContext扩展方法

public static class DataContextExentions
    {
        /// <summary>
        /// 打开连接
        /// </summary>
        /// <param name="dataContext"></param>
        private static void OpenConnection(this DataContext dataContext)
        {
            if (dataContext.Connection.State == ConnectionState.Closed)
            {
                dataContext.Connection.Open();
            }
        }

        /// <summary>
        /// 扩展ExecuteQuery方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataContext"></param>
        /// <param name="query"></param>
        /// <param name="withNoLock"></param>
        /// <returns></returns>
        public static List<T> ExecuteQuery<T>(this DataContext dataContext, IQueryable query, bool withNoLock)
        {
            DbCommand command = dataContext.GetCommand(query, withNoLock);

            dataContext.OpenConnection();

            using (DbDataReader reader = command.ExecuteReader())
            {
                return dataContext.Translate<T>(reader).ToList();
            }
        }

        /// <summary>
        /// 扩展ExecuteQuery方法2
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataContext"></param>
        /// <param name="query"></param>
        /// <param name="withNoLock"></param>
        /// <returns></returns>
        public static List<T> ExecuteQuery<T>(this DataContext dataContext, IQueryable query)
        {
            DbCommand command = dataContext.GetCommand(query);
            dataContext.OpenConnection();

            using (DbDataReader reader = command.ExecuteReader())
            {
                return dataContext.Translate<T>(reader).ToList();
            }
        }

        /// <summary>
        /// 扩展GetCommend方法,允许设置WithNoLick
        /// </summary>
        /// <param name="dataContext"></param>
        /// <param name="query"></param>
        /// <param name="withNoLock"></param>
        /// <returns></returns>
        private static SqlCommand GetCommand(this DataContext dataContext, IQueryable query, bool withNoLock)
        {
            SqlCommand command = (SqlCommand)dataContext.GetCommand(query);

            if (withNoLock)
            {
                command.CommandText = AddWithNoLock(command.CommandText);
            }

            return command;
        }

        /// <summary>
        /// 将Sql语句修改为with nolock
        /// </summary>
        /// <param name="cmdText"></param>
        /// <returns></returns>
        private static string AddWithNoLock(string cmdText)
        {
            IEnumerable<Match> matches =
                s_withNoLockRegex.Matches(cmdText).Cast<Match>()
                .OrderByDescending(m => m.Index);
            foreach (Match m in matches)
            {
                int splitIndex = m.Index + m.Value.Length;
                cmdText =
                    cmdText.Substring(0, splitIndex) + " WITH (NOLOCK)" +
                    cmdText.Substring(splitIndex);
            }

            return cmdText;
        }

        private static Regex s_withNoLockRegex =  new Regex(@"(] AS [td+])", RegexOptions.Compiled);
    }
}

2、DataContext扩展方法支持分页

/// <summary>
/// DataContext扩展方法
/// </summary>
public static class DataContextExtends
{
    /// <summary>
    /// ExecuteQuery方法扩展,将对象以redader方式转换为实体
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dataContext"></param>
    /// <param name="query"></param>
    /// <returns></returns>
    public static List<T> ExecuteQuery<T>(this DataContext dataContext, IQueryable<object> query)
    {
        return ExecuteQuery<T>(dataContext, query, 1, query.Cast<T>().Count());
    }

    /// <summary>
    /// ExecuteQuery方法扩展,代表分页的
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dataContext"></param>
    /// <param name="query"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    public static List<T> ExecuteQuery<T>(this DataContext dataContext, IQueryable<object> query, int pageIndex, int pageSize)
    {
        int total = query.Count();
        int totalPages = total / pageSize;

        if (total % pageSize > 0)
            totalPages++;

        if (pageIndex > totalPages)
        {
            pageIndex = totalPages;
        }
        if (pageIndex < 1)
        {
            pageIndex = 1;
        }
        query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
        DbCommand command = dataContext.GetCommand(query);
        dataContext.OpenConnection();
        using (DbDataReader reader = command.ExecuteReader())
        {
            return dataContext.Translate<T>(reader).ToList();
        }
    }
    private static void OpenConnection(this DataContext dataContext)
    {
        if (dataContext.Connection.State == ConnectionState.Closed)
            dataContext.Connection.Open();
    }

}

时间: 2024-08-11 03:38:12

linq to sql 扩展方法的相关文章

LINQ中的扩展方法

LINQ中的where(),OderByDescending().Select()并不是IEnumerable<T>的方法,却能使用这些方法,查阅了资料发现是用到了C#的扩展方法. 举个小例子: 定义一个静态类StringExtension和静态方法Foo,关键字this. public static class StringExtension { public static void Foo(this string s) { Console.WriteLine("Foo invok

使用Linq扩展方法时容易忽略的小问题

问题重现 下面直接给出用于说明文章主题的完整代码. //************************************************************ // // Linq扩展方法示例代码 // // Author:三五月儿 // // Date:2014/10/01 // // http://blog.csdn.net/yl2isoft // //************************************************************

LinQ—扩展方法

概述 本节主要讲解扩展方法,涉及LinQ的具体知识不多. 扩展方法的描述 .net framework为编程人员提供了很多的类,很多的方法,但是,不论.net framework在类中为我们提供了多么多的方法,有时候仍然不能满足我们的需求,例如:你想让字符串对象具有ToPascal方法,含义就是将字符串转化为Pascal格式,并返回,我们知道,.net framework提供的String类中并没有为我们提供相应的方法,此时,我们应该怎么做才可以达到我们的目的呢?有人说可以继承String类,这

Linq扩展方法获取单个元素

在使用Linq 提供的扩展方法时,First(OrDefault), Single(OrDefault), Last(OrDefault)都具有返回单个元素的功能.MSDN对这些方法的描述只有功能说明,没有关于内部的相关实现的描述说明. 首先我们来看下MSDN上关于这些扩展方法的官方描述: First: 返回序列中的第一个元素 . FirstOrDefault: 返回序列中的第一个元素:如果未找到元素,则返回默认值. Last:返回序列的最后一个元素. LastOrDefault: 返回序列中的

Windows Phone本地数据库(SQLCE):2、LINQ to SQL(翻译)(转)

首先.要说到的是,windows phone 7.1上基本的数据库功能是SQL Compact关于Mango的一个实现,使用linq to sql访问存储在数据库上的数据. 1.LINQ to SQL是什么 LINQ to SQL 是一个作为.NET Framework上的一部分的ORM(对象关系映射)框架.它允许你映射你的业务对象(business object)(模型类)到数据库中的表,然后可以不用写单一的SQL语句来访问或查询数据库中的数据.随着Mango的更新,LINQ to SQL现在

使用Linq中的Distinct方法对序列进行去重操作

使用Linq提供的扩展方法Distinct可以去除序列中的重复元素. 该方法具有以下两种重载形式: (1)public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source) (重载1) 通过使用默认的相等比较器对值进行比较并返回序列中的非重复元素. (2)publicstatic IQueryable<TSource> Distinct<TSour

扩展方法学习发展之路

大学学习的java,工作后转成了C#,由于工作需要,全力去学习了C#,学习中,相信大家都会有相同的疑惑,在判断一个字符串是否为空的时候总会用到string.IsNullOrEmpty(s)这个方法,最开始就想到了是不是反射,后面才知道这是c#的扩展方法,后面的内容慢慢讲解我对扩展方法由浅到深的理解与用法. 1:扩展方法的自定义实现,我这里特别用到了判断类型是否为数值类型的方法(可以去比较学习下),里面子定义了4个扩展方法 1 namespace ConsoleApplication1 2 { 3

LINQ to SQL 中 Concat、Union、Intersect、Except 方法的使用

?  前言 LINQ to SQL 中需要对两个或多个数据集进行操作,比如:合并.取交集等,主要使用下面四个方法,这四个方法都是 System.Linq.IQueryable<out T> 接口的扩展方法,并且都是延迟加载方法,下面是使用的简单示例. ?  示例数据,数据表:Subject(科目表).Score(成绩表) 1.   Concat() 方法 1)   方法声明 public static IQueryable<TSource> Concat<TSource>

Linq入门——什么是linq &amp; 扩展方法

一,什么是Linq linq(language integrated Query):语言集成查询: linq包含如下: 对对象的查询,对数据库的查询,对XML的查询. 那么,没有linq前我们是怎样查询的? 先看一个例子: 现在我们要查询大于50的数,: 在没有linq之前,我们的代码时这样的: 使用了linq查询: 首先,从直观上看,代码更加简洁,其次,对于查询部分,接近SQL语句,层次清晰,容易理解: 除了简单高效以为,LINQ的出现解决了很多问题: 1,面向对象与数据访问两个领域长期分裂,