Magic.Orm 基于C#的ORM框架,支持Sql Server/MySql/Oracle/Access/Sqlite等数据库,支持Lambda表达式快速上手0难度

/*=====================================
|| Author: jacky
|| Description: 数据访问基类
=====================================*/
 
using System;  
using System.Data;
using System.Linq; 
using System.Configuration;
using System.Collections.Generic;
using Magic.ORM;
 
namespace CRM.Core.Dal  
{
    /// <summary>
    /// 数据库Helper类
    /// </summary>
    public class DataRootBase  
    {
        /// <summary>
        /// 数据库连接字符串
        /// </summary>    
        public static string ConnectionString = ConfigurationManager.AppSettings["ConnectionString"];
        /// <summary>
        /// 数据库连接
        /// </summary>        
        public static readonly DbSession Context = new DbSession(DatabaseType.SqlServer, ConnectionString);
        
        #region 数据分页
        /// <summary>
        /// 数据分页(存储过程版pr_Pagination)
        /// </summary>
        /// <param name="TableName">表名或视图名</param>
        /// <param name="Fields">查询字段 如*或者字段名</param>
        /// <param name="OrderField">排序字段 如id desc</param>
        /// <param name="PageIndex">当前页码</param>
        /// <param name="PageSize">每页记录数</param>
        /// <param name="WhereStr">查询条件</param>
        /// <param name="TotalRecord">总记录数</param>
        /// <param name="TotalPage">总页数</param>
        /// <returns></returns>
        public static DataSet QueryPagingMssql(string TableName, string Fields, string OrderField,
            int PageIndex, int PageSize, string WhereStr, out int TotalRecord, out int TotalPage)
        {
            ProcSection proc = DataRootBase.Context.FromProc("pr_Pagination")
                                .AddInParameter("@TableName", DbType.String, TableName)
                                .AddInParameter("@Fields", DbType.String, Fields)
                                .AddInParameter("@OrderField", DbType.String, OrderField)
                                .AddInParameter("@SqlWhere", DbType.String, WhereStr)
                                .AddInParameter("@WholeContion", DbType.String, "count(1)")
                                .AddInParameter("@PageSize", DbType.Int32, PageSize)
                                .AddInParameter("@PageIndex", DbType.Int32, PageIndex)
                                .AddOutParameter("@TotalRecord", DbType.Int32)
                                .AddOutParameter("@TotalPage", DbType.Int32);
            var queryData = proc.ToDataSet();
            Dictionary<string, object> returnValue = proc.GetReturnValues();
            TotalRecord = Convert.ToInt32(returnValue.FirstOrDefault(q => q.Key.Equals("@TotalRecord")).Value);
            TotalPage = Convert.ToInt32(returnValue.FirstOrDefault(q => q.Key.Equals("@TotalPage")).Value);
            return queryData;
        }        
 
        /// <summary>
        /// 数据分页(存储过程版pr_Pagination)
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="TableName">表名或视图名</param>
        /// <param name="Fields">查询字段 如*或者字段名</param>
        /// <param name="OrderField">排序字段 如id desc</param>
        /// <param name="PageIndex">当前页码</param>
        /// <param name="PageSize">每页显示记录数</param>
        /// <param name="WhereStr">查询条件</param>
        /// <param name="TotalRecord">总记录数</param>
        /// <param name="TotalPage">总页数</param>
        /// <returns></returns>
        public static List<T> QueryPagingMssql<T>(string TableName, string Fields, string OrderField,
            int PageIndex, int PageSize, string WhereStr, out int TotalRecord, out int TotalPage)
        {
            ProcSection proc = DataRootBase.Context.FromProc("pr_Pagination")
                                .AddInParameter("@TableName", DbType.String, TableName)
                                .AddInParameter("@Fields", DbType.String, Fields)
                                .AddInParameter("@OrderField", DbType.String, OrderField)
                                .AddInParameter("@SqlWhere", DbType.String, WhereStr)
                                .AddInParameter("@WholeContion", DbType.String, "count(1)")
                                .AddInParameter("@PageSize", DbType.Int32, PageSize)
                                .AddInParameter("@PageIndex", DbType.Int32, PageIndex)
                                .AddOutParameter("@TotalRecord", DbType.Int32)
                                .AddOutParameter("@TotalPage", DbType.Int32);
            var queryData = proc.ToList<T>();
            Dictionary<string, object> returnValue = proc.GetReturnValues();
            TotalRecord = Convert.ToInt32(returnValue.FirstOrDefault(q => q.Key.Equals("@TotalRecord")).Value);
            TotalPage = Convert.ToInt32(returnValue.FirstOrDefault(q => q.Key.Equals("@TotalPage")).Value);
            return queryData;
        }
        
        /// <summary>
        /// 数据分页(自定义SQL语句ROW_NUMBER版)
        /// </summary>
        /// <param name="TableName">表名或视图名</param>
        /// <param name="Fields">查询字段 如*或者字段名</param>
        /// <param name="OrderField">排序字段 如id desc</param>
        /// <param name="PageIndex">当前页码</param>
        /// <param name="PageSize">每页显示记录数</param>
        /// <param name="WhereStr">查询条件</param>
        /// <param name="TotalRecord">总记录数</param>
        /// <param name="TotalPage">总页数</param>
        /// <returns></returns>
        public static DataSet QueryPagingByCustom(string TableName, string Fields, string OrderField, int PageIndex,
            int PageSize, string WhereStr, out int TotalRecord, out int TotalPage)
        {
            TotalRecord = Context.FromSql(string.Format("SELECT COUNT(1) FROM {0} where 1=1 {1}", TableName, WhereStr)).ToScalar<int>();
            TotalPage = (TotalRecord % PageSize != 0) ? (TotalRecord / PageSize + 1) : TotalRecord / PageSize;
            string sql = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {1}) AS ROWID, "
                + "{0} FROM {2} where 1=1 {3} ) AS t WHERE ROWID BETWEEN {4} AND {5}",
                Fields,
                OrderField,
                TableName,
                WhereStr,
                (PageIndex - 1) * PageSize + 1,
                PageIndex * PageSize);
            var a = Context.FromSql(sql).ToDataSet();
            return a;
        }        
 
        /// <summary>
        /// 数据分页(自定义SQL语句ROW_NUMBER版)
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="TableName">表名或视图名</param>
        /// <param name="Fields">查询字段 如*或者字段名</param>
        /// <param name="OrderField">排序字段 如id desc</param>
        /// <param name="PageIndex">当前页码</param>
        /// <param name="PageSize">每页显示记录数</param>
        /// <param name="WhereStr">查询条件</param>
        /// <param name="TotalRecord">总记录数</param>
        /// <param name="TotalPage">总页数</param>
        /// <returns></returns>
        public static IList<T> QueryPagingByCustom<T>(string TableName, string Fields, string OrderField, int PageIndex,
            int PageSize, string WhereStr, out int TotalRecord, out int TotalPage)
        {
            TotalRecord = Context.FromSql(string.Format("SELECT COUNT(1) FROM {0} where 1=1 {1}", TableName, WhereStr)).ToScalar<int>();
            TotalPage = (TotalRecord % PageSize != 0) ? (TotalRecord / PageSize + 1) : TotalRecord / PageSize;
            string sql = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {1}) AS ROWID, "
                + "{0} FROM {2} where 1=1 {3} ) AS t WHERE ROWID BETWEEN {4} AND {5}",
                Fields,
                OrderField,
                TableName,
                WhereStr,
                (PageIndex - 1) * PageSize + 1,
                PageIndex * PageSize);
            var a = Context.FromSql(sql).ToList<T>();
            return a;
        }
        #endregion  
    }
}
--SqlServer利用ROW_NUMBER快速分页,上面使用到的分页存储过程  
CREATE procedure [dbo].[pr_Pagination]  
@TableName varchar(500), --要进行分页的表,也可以用联接,如dbo.employee或dbo.employee INNER JOIN dbo.jobs ON (dbo.employee.job_id=dbo.jobs.job_id)  
@Fields varchar(500), --表中的字段,可以使用*代替  
@OrderField varchar(500), --要排序的字段  
@sqlWhere varchar(max), --WHERE子句  
@pageSize int, --分页的大小  
@pageIndex int, --要显示的页的索引  
@totalRecord int output,--记录总数  
@TotalPage int output, --页的总数  
@wholeContion varchar (1000) --存储过程中的条件  
as  
  
begin  
  
    --Begin Tran  
    Declare @sql nvarchar(4000);  
  
    Declare @Record int; --记录总数  
  
    --利用WHERE子句进行过滤  
    if (isnumeric(@wholeContion)=1 )  
    begin  
        set @sql = 'select @Record = count(*) from ' + @TableName + ' where 1=1 ' + @sqlWhere  
        EXEC sp_executesql @sql,N'@Record int OUTPUT',@Record OUTPUT  
        if (CAST(@wholeContion as int ) < @Record )  
        begin  
            set @Record = CAST(@wholeContion as int )  
        end   
    end  
    else  
    begin  
        set @sql = 'select @Record = ' + @wholeContion + ' from ' + @TableName + ' where 1=1 ' + @sqlWhere  
  
        --执行sql语句得到记录总数  
        EXEC sp_executesql @sql,N'@Record int OUTPUT',@Record OUTPUT  
    end   
      
    select @TotalPage=CEILING((@Record+0.0)/@PageSize)  
    select @totalRecord=@Record  
     --select @totalRecord  
    --select @TotalPage  
    --根据特定的排序字段为为行分配唯一ROW_NUMBER的顺序  
  
       set @sql = 'select * from (select ROW_NUMBER() over(order by ' + @OrderField + ') as rowId,' + @Fields + ' from ' + @TableName + ' where 1=1 ' + @SqlWhere  
    
  
    --确保当前页的索引在合理的范围之内  
  
    if @PageIndex<=0   
  
       Set @pageIndex = 1  
   
  
    --得到当前页在整个结果集中准确的ROW_NUMBER值  
  
    Declare @StartRecord int  
  
    Declare @EndRecord int  
  
    set @StartRecord = (@pageIndex-1)*@PageSize + 1  
  
    set @EndRecord = @StartRecord + @pageSize - 1  
  
   
  
    --输出当前页中的数据  
  
    set @Sql = @Sql + ') as t' + ' where rowId between ' + Convert(varchar(50),@StartRecord) + ' and ' +   Convert(varchar(50),@EndRecord)  
  print @Sql  
    Exec(@Sql)  
  
    --If @@Error <> 0  
       --Begin  
           --RollBack Tran            
       --End  
    --Else  
       --Begin  
           --Commit Tran            
       --End       
end 

Magic.Orm已在数百个成熟项目中应用,是比较完善的ORM框架(基于C#开发)。开发过程中参考了NBear与MySoft,吸取了其中的一些精华,加入新思想,
后期参考EF的Lambda语法进行大量扩展。

为什么选择Magic.Orm?

  • 上手简单,0学习成本。使用方便,按照sql书写习惯编写C#.NET代码。功能强大。
  • 高性能,接近手写Sql。
  • 体积小(不到200kb,仅一个dll)。
  • 完美支持Sql Server(2000至最新版),MySql,Oracle,Access,Sqlite等数据库。
  • 支持大量Lambda表达式写法。
  • 不需要像NHibernate的XML配置,不需要像EF的各种数据库连接驱动,集成简单。

购买源码 请联系QQ:7400799(请备注 "ORM")

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Magic.ORM;
 
namespace Ydt.Core
{
    class MagicOrmSample
    {
        //Magic ORM示例
        //包含增删改查,自定义分页,存储过程分页,调用存储过程,复杂查询,批处理,自定义缓存等
        //var str = "";
        /*    SELECT   TOP 10 * FROM [TestTable]      */
        //Console.WriteLine("==================================");
        //str = "";
        //var list = DataRootBase.Context.From<TestTable>().Top(10).ToList();
        //foreach (var item in list)
        //{
        //    str += string.Format("{0}---{1}---{2}---{3}---{4}
", item.D_Id, item.D_Name, item.D_Password, item.D_Else, item.D_Amount);
        //}
        //Console.WriteLine(str);
        //Console.ReadKey();
 
        /*===============================================================================================*/
        /* exec sp_executesql N' SELECT count(*) as r_cnt FROM [TestTable] WHERE [TestTable].[D_Name] LIKE @D_Name1',N'@D_Name1 nvarchar(4)',@D_Name1=N'名称1%' */
        //Console.WriteLine("==================================");
        //str = "";
        //var count = DataRootBase.Context.From<TestTable>()
        //    .Where(d => d.D_Name.Contains("名称1"))
        //    .Count();
        //Console.WriteLine(count);
 
 
        /*===============================================================================================*/
        /*  SELECT   [TestTable].[D_Id],[TestTable].[D_Name] FROM [TestTable]  */
        //Console.WriteLine("==================================");
        //str = "";
        //var list1 = DataRootBase.Context.From<TestTable>()
        //    .Select(d => new { d.D_Id, d.D_Name }).Top(5).ToList();
        //foreach (var item in list1)
        //{
        //    str += string.Format("{0}---{1}
", item.D_Id, item.D_Name);
        //}
        //Console.WriteLine(str);
 
 
        /*===============================================================================================*/
        ///*  SELECT   TOP 5 [TestTable].[D_Id] AS [ID],[TestTable].[D_Name] AS [UserName] FROM [TestTable]   */
        //Console.WriteLine("==================================");
        //str = "";
        //var list2 = DataRootBase.Context.From<TestTable>().Select(d => new { ID = d.D_Id, UserName = d.D_Name }).Top(5).ToDataTable();
        //foreach (DataRow item in list2.Rows)
        //{
        //    str += string.Format("{0}---{1}
", item["ID"], item["UserName"]);
        //}
        //Console.WriteLine(str);
 
        /*======================================视图分页=================================================*/
        //强类型
        //str = "";
        //var list2 = DataRootBase.Context.From<JianKu.Model.vw_test>()
        //    .Page(10, 50).ToList();
        //foreach (var item in list2)
        //{
        //    str += string.Format("{0}---{1}
", item.D_Id, item.D_Name);
        //}
        //Console.WriteLine(str);
        //Console.ReadKey();
 
        //弱类型
        //str = "";
        //var list2 = DataRootBase.Context.From("vw_test")
        //    .Page(10, 10)
        //    .OrderBy(new OrderByClip("D_Id", Magic.ORM.OrderByOperater.ASC))
        //    .ToDataTable();
        //foreach (DataRow item in list2.Rows)
        //{
        //    str += string.Format("{0}---{1}
", item["D_Id"], item["D_Name"]);
        //}
        //Console.WriteLine(str);
        //Console.ReadKey();
 
 
        /*=================================执行分页存储过程,返回结果集(以后项目推荐使用)=============================================*/
        /*=====批量插入方法,ORM内部存在事务,不用担心某些数据插入成功,某些数据插入失败。===============*/
        //str = "";
        //int TotalRecord = 0;
        //int TotalPage = 0;
        //var list2 = DataRootBase.QueryPagingMssql<TestTable>("TestTable", "*", "D_Id asc", 1, 5, "", out TotalRecord, out TotalPage);
        //foreach (var item in list2)
        //{
        //    str += string.Format("{0}---{1}
", item.D_Id, item.D_Name);
        //}
        //str += string.Format("总记录数{0}---总页数{1}
", TotalRecord, TotalPage);
        //Console.WriteLine(str);
        //Console.ReadKey();
 
 
 
 
        /*======================================执行存储过程 带输入输出参数 且有多个结果集=================================================*/
        /*存储过程
                ALTER PROCEDURE [dbo].[sp_test]
                   @userId INT,
                   @count int out
                AS
                BEGIN
                 SELECT TOP 5 * FROM dbo.TestTable
                 SELECT para1='张三',para2='男',para3='21',userCount=15662
                END             
         */
        //DataSet ds = DataRootBase.Context.FromProc("sp_test")
        //                .AddInParameter("@userId", DbType.Int32, 100)
        //                .AddOutParameter("@count",DbType.Int32)
        //                .ToDataSet();
 
        //str += "==============datatable1数据====================
";
        //foreach (DataRow item in ds.Tables[0].Rows)
        //{
        //    str += string.Format("{0}---{1}
", item["D_Id"], item["D_Name"]);
        //}
        //str += "==============datatable2数据====================
";
        //foreach (DataRow item in ds.Tables[1].Rows)
        //{
        //    str += string.Format("{0}---{1}---{2}---{3}
", item["para1"], item["para2"], item["para3"], item["userCount"]);
        //}
        //Console.WriteLine(str);
        //Console.ReadKey();
 
 
        /*===============================================================================================*/
        /* exec sp_executesql N'INSERT INTO [TestTable] ([D_Amount],[D_Name]) VALUES (@D_Amount2,@D_Name3);select scope_identity()',
         * N'@D_Amount2 decimal(4,0),@D_Name3 nvarchar(4)',@D_Amount2=5811,@D_Name3=N'我是李四' */
        //Console.WriteLine("==================================");
        //str = "";
        //var newModel = new TestTable()
        //{
        //    D_Name = "我是李四",
        //    D_Password = "123456",
        //    D_Else = "123"
        //};
        //var count1 = DataRootBase.Context.Insert<TestTable>(newModel);
        //Console.WriteLine(count1);
        //Console.ReadKey();
 
 
        /*===============================================================================================*/
        /*=====批量插入方法,ORM内部存在事务,不用担心某些数据插入成功,某些数据插入失败。===============*/
        //var newList = new List<TestTable>();
        //newList.Add(new TestTable()
        //{
        //    D_Name = "200我是李四",
        //    D_Password = "123456",
        //    D_Else = "123"
        //});
        //newList.Add(new TestTable()
        //{
        //    D_Name = "200我是李四",
        //    D_Password = "123456",
        //    D_Else = "234"
        //});
        //var count = DataRootBase.Context.Insert<TestTable>(newList);
        //Console.WriteLine(count);
        //Console.ReadKey();
 
        /*===============================================================================================*/
        /* exec sp_executesql N'UPDATE [TestTable] SET [D_Name]=@D_Name2 WHERE [TestTable].[D_Id] = @D_Id1',
         * N'@D_Name2 nvarchar(6),@D_Id1 int',@D_Name2=N'我是修改后的',@D_Id1=10006*/
        //var uptModel = new TestTable();
        //uptModel.D_Name = "我是修改后的";  //修改表中所有数据 使用UpdateAll
        //var count = DataRootBase.Context.Update<TestTable>(uptModel, d => d.D_Id == 10006);
        //Console.WriteLine(count);
        //Console.ReadKey();
 
        /*===============================================================================================*/
        /*=======================================子查询条件修改==========================================*/
 
        //SQL语句:UPDATE table SET sex='man' WHERE id IN
        //    (SELECT id FROM table WHERE name='aa')
        //var uptModel = new TestTable();
        //uptModel.D_Name = "man";
        //var count2 = DataRootBase.Context.Update<TestTable>(uptModel, TestTable._.D_Id.SubQueryIn(
        //    DB.Content.From<TestTable>().Select(d => d.id).Where(d => d.name == "aa")
        //));             
 
 
        /*=======================================删除操作==========================================*/
        /*=======================================删除操作==========================================*/
        /*             
            根据主键值删除单条数据:
            //SQL语句:DELETE FROM table WHERE id=1
            var count = DB.Context.Delete<table>(d => d.id == 1);
            //或者简写:
            var count = DB.Context.Delete<table>(1);
            //同样也适用于Guid主键类型
            var count = DB.Context.Delete<table>(d => d.id == Guid.Parse("..."));
            //简写:
            var count = DB.Context.Delete<table>(Guid.Parse("..."));
         * 
            根据主键值批量删除数据:
            //SQL语句:DELETE FROM table WHERE id IN(1,2,3)
            var ids = new List<int>();
            ids.Add(1);
            ids.Add(2);
            ids.Add(3);
            var count = DB.Context.Delete<table>(d => d.id.In(ids));
            //也可以这样写:
            var count = DB.Context.Delete<table>(d => d.id.In(1,2,3));
         * 
            根据实体删除单条数据:
            //SQL语句:DELETE FROM table WHERE id=1
            var model = DB.Context.From<table>().First();
            if(model == null)
            {
                return "不存在要删除的数据";
            }
            //会根据主键自动添加where条件:WHERE id=model.id
            var count = DB.Context.Delete<table>(model);
            //同以下写法:
            var count = DB.Context.Delete<table>(d => d.id == model.id);
         * 
            根据实体批量删除数据:
            //SQL语句:DELETE FROM table WHERE id IN(1,2,3)
            var list = DB.Context.From<table>().ToList();
            //批量删除方法内部有事务,会自动添加where条件:WHERE id IN(list主键数据)
            var count = DB.Context.Delete<table>(list);
            //同以下写法:
            var ids = list.Select(d => d.id).ToList();
            var count = DB.Context.Delete<table>(d => d.id.In(ids));
         *
            子查询条件删除:
            //SQL语句:DELETE FROM table WHERE id IN
            //    (SELECT id FROM table WHERE name='aa')
            var count2 = DB.Content.Delete<table>(table._.id.SubQueryIn(
                DB.Content.From<table>().Select(d => d.id).Where(d => d.name == "aa")
            ));             
         */
 
 
        /*=======================================直接执行SQL语句==========================================*/
        /*=======================================直接执行SQL语句==========================================*/
        /*
            //直接执行SQL语句:
            //返回List<table>数据
            var list = DataRootBase.Context.FromSql("SELECT * FROM vw_test")
                .ToList<vw_test>();
            //也可以指定任意类映射返回:
            public class ViewTable
            {
                public string name {get;set;}
                public string sex {get;set;}
            }
            //返回List<ViewTable>,将成功映射name,sex。id无法映射,因为没有为ViewTable定义id属性。
            var list = DB.Context.FromSql("SELECT id,name,sex FROM table").ToList<ViewTable>();
         * 
            执行带参SQL:
            var list = DB.Context.FromSql("SELECT * FROM table WHERE name=@name AND id=@id")
                            .AddInParameter("@name", DbType.String, "aa")
                            .AddInParameter("@id", DbType.Int32, "1")
                            .ToList<table>();
            //也可以先拼接好参数,再一次性传入
            var params = new DbParameter[2];
            params[0] = DataRootBase.Context.Db.DbProviderFactory.CreateParameter();
            params[0].DbType = DbType.String;
            params[0].ParameterName = "@name";
            params[0].Value = "aa";
            params[1] = DB.Context.Db.DbProviderFactory.CreateParameter();
            params[1].DbType = DbType.Int32;
            params[1].ParameterName = "@id";
            params[1].Value = 1;
            DB.Context.FromSql("SELECT * FROM table WHERE name=@name AND id=@id")
                .AddParameter(params)
                .ToDataTable();
         * 
            返回类型还可以如下:
            //返回DataReader
            IDataReader ToDataReader()
            //返回DataSet
            DataSet ToDataSet()
            //返回受影响的条数
            int ExecuteNonQuery()
            //返回单个值,第一行第一列
            object ToScalar()
            //返回执行类型的值 
            TResult ToScalar<TResult>()
            //返回第一条实体
            TEntity ToFirst<TEntity>()             
         */
 
 
 
        /*=======================================执行存储过程==========================================*/
        /*=======================================执行存储过程==========================================*/
        /*
            执行存储过程是通过FromProc方法来完成的。
            执行无参数存储过程如下:
            DataRootBase.Context.FromProc("Ten Most Expensive Products").ToDataTable();
            "Ten Most Expensive Products"就是存储过程名称。
         * 
            执行带参数的存储过程:
            DataRootBase.Context.FromProc("Sales by Year")
                            .AddInParameter("Beginning_Date", DbType.DateTime, "1995-01-01")
                            .AddInParameter("Ending_Date", DbType.DateTime, "1996-12-01")
                            .ToDataTable();
            数据库中该存储过程
            create procedure "Sales by Year" 
                @Beginning_Date DateTime, @Ending_Date DateTime AS
            SELECT Orders.ShippedDate, Orders.OrderID, "Order Subtotals".Subtotal, DATENAME(yy,ShippedDate) AS Year
            FROM Orders INNER JOIN "Order Subtotals" ON Orders.OrderID = "Order Subtotals".OrderID
            WHERE Orders.ShippedDate Between @Beginning_Date And @Ending_Date
            GO
            有两个参数,分别是Beginning_Date和Ending_Date。
         * 
 
            存储过程和sql语句的执行类似,不过存储过程多了参数,就是会有输入输出参数。
 
            通过
            AddInputOutputParameter  方法添加输入输出参数 
            AddOutParameter  方法添加输出参数
            AddReturnValueParameter  方法添加返回参数
 
            返回参数值,示例如下:
            ProcSection proc = DataRootBase.Context.FromProc("testoutstore")
                 .AddInParameter("in1", System.Data.DbType.Int32, 1)
                 .AddOutParameter("out1", System.Data.DbType.Int32)
                 .AddOutParameter("out2", System.Data.DbType.String);
            proc.ExecuteNonQuery();
            Dictionary<string, object> returnValue =
            proc.GetReturnValues();
            foreach (KeyValuePair<string, object> kv in returnValue)
            {
                Response.Write("ParameterName:" + kv.Key + "    ;ReturnValue:" + Convert.ToString(kv.Value));
                Response.Write("<br />");
            }
            其中GetReturnValues()方法就是回去返回值。             
         */
 
 
        /*=======================================Where条件查询==========================================*/
        /*=======================================Where条件查询==========================================*/
        /*
            普通的Where条件写法:
            //SQL语句:SELECT * FROM table WHERE name='aa' AND (id=1 OR sex='man')
            var list = DB.Context.From<table>()
                            .Where(d => d.name == "aa" && (d.id == 1 || d.sex == 'man'))
                            .ToList();
         * 
            Like模糊查询:
            //SQL语句:SELECT * FROM table WHERE name LIKE '%aa%' 
            //            AND name LIKE 'dos%' AND name LIKE '%IT'
            var list = DB.Context.From<table>()
                            .Where(d => d.name.Like("aa") 
                                        && d.name.StartsWith("dos") 
                                        && d.name.EndsWith("IT"))
                            .ToList();
         * 
            In、Not In查询:
            //SQL:SELECT * FROm table WHERE id IN(1,2,3) AND name NOT IN('dos','IT')
            var list = DB.Context.From<table>()
                            .Where(d => d.id.In(1,2,3) && d.name.NotIn("dos","IT"))
                            .ToList();
            //也可以指定一个数据集做为条件
            var listParam = new List<int>();
            listParam.Add(1);
            listParam.Add(2);
            listParam.Add(3);
            var list = DB.Context.From<table>()
                            .Where(d => d.id.In(listParam))
                            .ToList();
         * 
            Where条件拼接使用Where类:
            //sql语句:SELECT * FROM table WHERE name='aa' AND id=1
            var where = new Where<table>();
            where.And(d => d.name == "aa");
            where.And(d => d.id == 1);
            var list = DB.Context.From<table>()
                            .Where(where)
                            .ToList();
         * 
            
            //多表条件拼接:
            //SQL语句:SELECT * FROM table a 
            //            INNER JOIN table2 b ON a.id=b.aid
            //            INNER JOIN table3 c ON a.id=c.aid
            //            WHERE a.id=1 AND b.id=2 AND c.id=3
            
            var where = new Where<table>();
            where.And(a => a.id == 1);
            where.And<table2>((a,b) => b.id == 2);
            where.And<table3>((a,c) => c.id == 3);
            var list = DB.Context.From<table>()
                            .<table2>((a,b) => a.id == b.aid)
                            .InnerJoin<table3>((a,c) => a.id == c.aid)
                            .Where(where)
                            .ToList();
            //上面的where还可以这样写:
            var where = new Where<table>();
            where.And<table2,table3>((a,b,c) => a.id == 1 && b.id == 2 && c.id == 3);             
         */
 
 
 
        /*=======================================多表联合查询==========================================*/
        /*==============强烈推荐视图方式多表联合查询,配合CodeSmith自动生成强类型实体类===================*/
        /*  情况1,都关联主表
                //SQL语句:SELECT a.*,b.*,c.name FROM table a 
                //            INNER JOIN table2 b ON a.id=b.aid
                //            LEFT JOIN table3 c ON a.id=c.aid
                var list = DB.Context.From<table>()
                                .Select(table._.All,
                                        table2._.All,
                                        table3._.name)
                                .InnerJoin<table2>((a,b) => a.id == b.aid)
                                .LeftJoin<table3>((a,c) => a.id == c.aid)
                                .ToList();
                //由于返回的数据是List<table>数据,如果table实体类不包含table3的name字段
                //那么将无法映射这些数据,所以需要为table扩展属性
                //新建带有partial修饰的table扩展类,与table实体类在同一命名空间下:
                using Model;
                public partial class table
                {
                    public string name { get; set;}
                    //可以继续扩展table2中的字段
                }
                //这样.ToList()返回的List<table>数据就包含table3.name的数据了。
                //如果您觉得关联表太多,字段太多,扩展麻烦,可以直接返回.ToDataTable()。
         * 
         * 
         * 
           //情况2 表之间任意关联
            SELECT * FROM dbo.Street a 
            INNER JOIN dbo.Area b ON a.AreaId=b.AreaId
            INNER JOIN dbo.City c ON b.CityId=c.CityId
            INNER JOIN dbo.Province d ON c.ProId=d.ProId
         * 
           var str = "";
           var list= DataRootBase.Context.From<Street>()
                .Select(Street._.All,
                        Area._.AreaName,
                        City._.CityName,
                        Province._.ProName
               )
                .InnerJoin<Area>((a, b) => a.AreaId == b.AreaId)
                .InnerJoin<City>(Area._.CityId == City._.CityId)
                .InnerJoin<Province>(City._.ProId == Province._.ProId).ToDataTable();  //弱类型数据集合,或者自己扩展一个新实体类接收强类型数据集合
           foreach (DataRow item in list.Rows)
           {
               str += string.Format("{0}---{1}---{2}---{3}---{4}
", item["StreetId"], item["StreetName"], item["AreaName"], item["CityName"], item["ProName"]);
           }
           Console.WriteLine(str);
           Console.ReadKey(); 
         * 
         * 
         * 
         方法对照表:
            方法                SQL
            .InnerJoin<T>()     inner join
            .LeftJoin<T>()        left join
            .RightJoin<T>()        right join
            .CrossJoin<T>()        cross join
            .FullJoin<T>(0      full join
         */
 
 
        /*=======================================分组和排序==========================================*/
        /*=======================================分组和排序==========================================*/
        /*
         * 自己指定排序
                DataRootBase.Context.From<Products>()
                .Page(10, 2)
                .Where(Products._.CategoryID.SelectIn(1, 2, 3))
                .OrderBy(Products._.CategoryID.Asc)
                .ToList();   
         * 多个字段排序则如下操作
                DataRootBase.Context.From<Products>()
                .OrderBy(Products._.CategoryID.Asc && Products._.ProductID.Asc)
                .ToList();
         * 分组
        通过方法GroupBy来设置按照哪些字段分组。
        例如:
        DataRootBase.Context.From<Products>()
                        .GroupBy(Products._.ProductName.GroupBy)
                        .Select(Products._.ProductName)
                        .ToDataTable();
        生成的sql:
        Text: 
        SELECT [Products].[ProductName] FROM [Products] 
        GROUP BY [Products].[ProductName] 
         * 按照多个字段分组和多个排序类似。
        DataRootBase.Context.From<Products>()
                        .GroupBy(Products._.ProductName.GroupBy && Products._.ProductID.GroupBy)
                        .Select(Products._.ProductName,Products._.ProductID)
                        .ToDataTable();
        sql:
        Text: 
        SELECT [Products].[ProductName],[Products].[ProductID] FROM [Products] GROUP BY [Products].[ProductName],[Products].[ProductID] 
         */
 
 
        /*=======================================数据分页==========================================*/
        /*=======================================数据分页==========================================*/
        /*
            top方法:
            DataRootBase.Context.From<Products>()
                            .Top(10)
                            .ToList();
            该查询时查询products表中的前10条记录,生成的sql语句如下:(如何输出查看组件生成的sql)
            Text: 
            SELECT TOP 10 * FROM [Products] 
 
 
            from方法:
            DataRootBase.Context.From<Products>()
                            .From(3, 8)
                            .ToList();
            查找第3条到第8条的数据(包括第3条和第8条),生成的sql语句如下:
            Text: 
            SELECT * FROM 
            ( SELECT TOP 6 * FROM 
            ( SELECT TOP 8 * FROM [Products] ORDER BY [Products].[ProductID] ASC)
             AS tempIntable ORDER BY [ProductID] DESC)
             AS tempOuttable ORDER BY [ProductID] ASC 
 
 
            page方法:
            DataRootBase.Context.From<Products>()
                            .Page(10, 2)
                            .ToList();
            查询每页10条的第2页数据,sql语句如下:
            Text: 
            SELECT * FROM 
            ( SELECT TOP 10 * FROM 
            ( SELECT TOP 20 * FROM [Products] ORDER BY [Products].[ProductID] ASC)
             AS tempIntable ORDER BY [ProductID] DESC)
             AS tempOuttable ORDER BY [ProductID] ASC 
            可以看出from方法和page方法生成的sql语句是格式是一样的,其实page方法最终还是调用from方法,
            如果from的startIndex参数等于1就会调用top方法来查询。
 
            默认情况下我们并没有设置排序,组件则会自动添加一个排序,如果有主键则选主键排序,不然选一个其他列排序。
 
            当然在很多情况下我们是需要设置哪些列排序的。
            例如:
            DataRootBase.Context.From<Products>()
                            .Page(10, 2)
                            .OrderBy(Products._.UnitPrice.Desc)
                            .Where(Products._.CategoryID == 2)
                            .ToList();
            查询条件是categoryid等于2,按照unitprice倒叙排序,每页10条的第2页数据。
            生成的sql如下:
            Text: 
            SELECT * FROM 
            ( SELECT TOP 2 * FROM [Products] WHERE [Products].[CategoryID] = @bee7551993404c8592f07f9b01710bb5 ORDER BY [Products].[UnitPrice] ASC)
             AS temp_table ORDER BY [UnitPrice] DESC 
            Parameters: 
            @bee7551993404c8592f07f9b01710bb5[Int32] = 2 
            这样的sql语句是不是出乎意料啊,原来符合条件的查询第二页只有2条数据,所以查询的时候就直接unitprice正序top 2就完结了。
 
            我们把条件去掉再看看:
            DataRootBase.Context.From<Products>()
                            .Page(10, 2)
                            .OrderBy(Products._.UnitPrice.Desc)
                            //.Where(Products._.CategoryID == 2)
                            .ToList();
            生成的sql如下:
            Text: 
            SELECT * FROM 
            ( SELECT TOP 10 * FROM 
            ( SELECT TOP 20 * FROM [Products] ORDER BY [Products].[UnitPrice] DESC)
             AS tempIntable ORDER BY [UnitPrice] ASC)
             AS tempOuttable ORDER BY [UnitPrice] DESC 
            这样算是正常的生成格式了。
 
            以上的sql脚本都是在sql server2000下生成的。
 
            其实在查询过程中组建还会自动查询了count()符合条件的记录数,所以在大数据的情况下,效率不会很好。
 
            如果你设置组建的数据库是sql server2005则不会去查询 count,而是直接通过row_number()来查询,来获得更好的效率。(oracle则是rownum实现)
 
            下面来sql server2005例子:
            DataRootBase.Context.From<Products>()
                            .Page(10, 2)
                            .OrderBy(Products._.UnitPrice.Desc)
                            //.Where(Products._.CategoryID == 2)
                            .ToList();
            代码还是上面的例子的,生成的sql:
            Text: 
            SELECT * FROM 
            ( SELECT *,row_number() over( ORDER BY [Products].[UnitPrice] DESC) AS tmp__rowid FROM [Products] ) AS tmp_table 
            WHERE (tmp__rowid BETWEEN 11 AND 20) 
            方法的调用还是一样的,所以如果from的参数startIndex等于1,还是优先使用top,并没有使用row_numer()。             
         */
 
 
        /*=======================================子查询==========================================*/
        /*=======================================子查询==========================================*/
        /*
            查询条件的值来自另外一次查询。
            例如  sqlserver sql:  
            select * from products where categoryid=(select top 1 categoryid from categories where categoryname=’produce’)
            这条sql的实现代码如下:
            DataRootBase.Context.From<Products>()
                            .Where(Products._.CategoryID
                            .SubQueryEqual(DataRootBase.Context.From<Categories>().Where(Categories._.CategoryName == "Produce").Select(Categories._.CategoryID).Top(1)))
                            .ToList();
            对比一下组件生成的sql
            Text: 
            SELECT * FROM [Products] 
            WHERE [Products].[CategoryID] = 
           ( SELECT TOP 1 [Categories].[CategoryID] FROM [Categories] WHERE [Categories].[CategoryName] = @174b5c8999e2480594cdc08ab4d8e5bd) 
            Parameters: 
            @174b5c8999e2480594cdc08ab4d8e5bd[String] = Produce 
 
            子查询方法对应sql表如下:
            方法名称    sql
            SubQueryEqual    =
            SubQueryNotEqual    <>
            SubQueryLess    <
            SubQueryLessOrEqual    <=
            SubQueryGreater    >
            SubQueryGreaterOrEqual    >=
            SubQueryIn    in
            SubQueryNotIn    not in
 
            再写一个例子
            DataRootBase.Context.From<Products>()
                            .Where(Products._.CategoryID
                            .SubQueryNotIn(DataRootBase.Context.From<Categories>().Where(Categories._.CategoryName == "Produce").Select(Categories._.CategoryID)))
                            .ToList();
            生成的sql如下
            Text: 
            SELECT * FROM [Products] 
            WHERE [Products].[CategoryID] 
            NOT IN ( SELECT [Categories].[CategoryID] FROM [Categories] WHERE [Categories].[CategoryName] = @32365a219b864e5fbeb7959a6071d4c8) 
            Parameters: 
            @32365a219b864e5fbeb7959a6071d4c8[String] = Produce 
            子查询是不是也变的很简单的呢了。             
         */
 
 
        /*=======================================事务==========================================*/
        /*=======================================事务==========================================*/
        /*
            组件提供了简单的事务,并没有过多的封装。
            先上个例子:
            using (DbTrans trans = DataRootBase.Context.BeginTransaction())
            {
                DataRootBase.Context.Update<Products>(trans, Products._.ProductName, "apple", Products._.ProductID == 1);
                DataRootBase.Context.Update<Products>(trans, Products._.ProductName, "egg", Products._.ProductID == 2);
                trans.Commit(); //必须提交,不然就执行不成功了。
            }
 
            如果使用try catch的写法如下:
            DbTrans trans = DataRootBase.Context.BeginTransaction();
            try
            {
                DataRootBase.Context.Update<Products>(trans, Products._.ProductName, "apple", Products._.ProductID == 1);
                DataRootBase.Context.Update<Products>(trans, Products._.ProductName, "egg", Products._.ProductID == 2);
                trans.Commit();
            }
            catch
            {
                trans.Rollback();
            }
            finally
            {
                trans.Close();
            }
             insert、update、delete方法都提供了DbTransaction参数
            所以也只是添加,修改,删除可以提交事务。
 
            存储过程和直接sql执行也是可以添加事务的。
            例如:
            DbTrans trans = DataRootBase.Context.BeginTransaction();
            DataRootBase.Context.FromProc("Ten Most Expensive Products").SetDbTransaction(trans);
            通过SetDbTransaction方法来添加事务。
            FromSql也是一样。
 
            也可以设置事务的级别,如下:
            DbTrans trans = DataRootBase.Context.BeginTransaction(IsolationLevel.ReadCommitted);             
         */
 
 
        /*=======================================批处理==========================================*/
        /*=======================================批处理==========================================*/
        /*
            批处理就是提交的脚本不是马上执行,而是到一定数量才提交。
            还是先上例子
            using (DbBatch batch = DataRootBase.Context.BeginBatchConnection(10))
            {
                batch.Update<Products>(Products._.ProductName, "apple", Products._.ProductID == 1);
                batch.Update<Products>(Products._.ProductName, "pear", Products._.ProductID == 2);
                batch.Update<Products>(Products._.ProductName, "orange", Products._.ProductID == 3);
            }
                         * 默认是10条sql执行一次。也可以自定义。
 
            DbBatch batch = DataRootBase.Context.BeginBatchConnection(20)
            这样就设置了20条sql执行一次。
            并可以设置内部事务级别.
            DbBatchbatch = DataRootBase.Context.BeginBatchConnection(20, IsolationLevel.ReadCommitted)
 
            也可强制性执行:
            using (DbBatch batch = DataRootBase.Context.BeginBatchConnection())
            {
                batch.Update<Products>(Products._.ProductName, "apple", Products._.ProductID == 1);
                batch.Update<Products>(Products._.ProductName, "pear", Products._.ProductID == 2);
                batch.Execute();
                batch.Update<Products>(Products._.ProductName, "orange", Products._.ProductID == 3);
            }
            执行batch.Execute(),就会将之前的sql脚本先提交。
                         try catch的写法如下:
            DbBatch batch = DataRootBase.Context.BeginBatchConnection();
            try
            {
                batch.Update<Products>(Products._.ProductName, "apple1", Products._.ProductID == 1);
                batch.Update<Products>(Products._.ProductName, "pear1", Products._.ProductID == 2);
                batch.Update<Products>(Products._.ProductName, "orange1", Products._.ProductID == 3);
            }
            catch
            {
                //do something
            }
            finally
            {
                batch.Close();
            }
            效果和第一个例子是一样的。
 
            批处理也是比较简单的。
         */
 
 
        /*=======================================自定义缓存==========================================*/
        /*=======================================自定义缓存==========================================*/
        /*
            配置的缓存并不能满足我们的需求,例如有时候需要刷新缓存,或者某次查询缓存时间或者缓存依赖不一样等。
            刷新缓存
            例如:
            DataRootBase.Context.From<Products>().Where(Products._.ProductID == 1).Refresh().ToFirst();
            Refresh()方法设置了刷新缓存,即不从缓存中读取,直接从数据库读取最新数据,并重新缓存。
            设置查询的缓存有效期。
            例如:
            DataRootBase.Context.From<Products>().Where(Products._.ProductID == 1).SetCacheTimeOut(180).ToFirst();
            设置该查询的缓存时间为180秒。
            该设置会覆盖默认缓存配置,并且缓存配置中没有实体设置,也会缓存。
            当下次执行:
            DataRootBase.Context.From<Products>().Where(Products._.ProductID == 1).ToFirst();
            在180秒内缓存有效。
                
         * 设置缓存依赖。
            例如:
            System.Web.Caching.CacheDependency cacheDep = new System.Web.Caching.CacheDependency(Server.MapPath("~/2.txt"));
            DataRootBase.Context.From<Products>().Where(Products._.ProductID == 1).SetCacheDependency(cacheDep).ToFirst();
            设置该查询缓存的缓存依赖为2.txt文件。
            该设置会覆盖默认缓存配置,并且缓存配置中没有实体设置,也会缓存。
            当再次执行:
            DataRootBase.Context.From<Products>().Where(Products._.ProductID == 1).ToFirst();
            如果2.txt文件没有改变,缓存是不会失效的。
            当然这几个方法也可以同时使用。
            缓存是根据生成的sql作为缓存依据的,所以写法确保一致,特别是条件的先后顺序,才能有效利用缓存,否则就要浪费内存了。             
         */
    }
}
原文地址:https://www.cnblogs.com/smartsmile/p/14415875.html