SqlSugar 用法大全


十年河東,十年河西,莫欺少年窮

學無止境,精益求精

官方文檔:::::http://www.donet5.com/Doc/99999999999/1197

接着上篇博客案例:https://www.cnblogs.com/chenwolong/p/SqlSugar.html

簡單查詢:

        static SugarDbContext sugar = new SugarDbContext();
        static void Main(string[] args)
        {
            var db = sugar.Db;
            //查詢所有
            var AllStudent = db.Queryable<Student>().ToList();
            //取前5條
            var top5 = db.Queryable<Student>().Take(5).ToList();
            //無鎖查詢
            var getAllNoLock = db.Queryable<Student>().With(SqlWith.NoLock).ToList();
            //根據主鍵查詢
            var getByPrimaryKey = db.Queryable<Student>().InSingle("0000d82f-b1f2-4c7d-a3b9-6c70f9678282");
            //查詢單條沒有數據返回NULL, Single超過1條會報錯,First不會
            //var getSingleOrDefault = db.Queryable<Student>().Single(); //會報錯,數據量大於一條
            var getSingleOrDefault = db.Queryable<Student>().Where(A=>A.StudentID== "0000d82f-b1f2-4c7d-a3b9-6c70f9678282").Single();
            var getFirstOrDefault = db.Queryable<Student>().First();
            //UNION ALL Count = 2420838  240多萬條數據
            var UNIONLst = db.UnionAll<Student>(db.Queryable<Student>(), db.Queryable<Student>()).ToList();
            //in 查詢
            var in1 = db.Queryable<Student>().In(A => A.StudentID, new string[] { "000136bf-f968-4a59-9091-bae8ebca42fb", "00020ba7-44e6-494c-8fcb-c1be288a39b3" }).ToList();
            //主鍵 In (1,2,3)  不指定列, 默認根據主鍵In
            var in2 = db.Queryable<Student>().In(new string[] { "000136bf-f968-4a59-9091-bae8ebca42fb", "00020ba7-44e6-494c-8fcb-c1be288a39b3" }).ToList();
            //in 查詢
            List<string> array = new List<string>{ "000136bf-f968-4a59-9091-bae8ebca42fb", "00020ba7-44e6-494c-8fcb-c1be288a39b3" };
            var in3 = db.Queryable<Student>().Where(it => array.Contains(it.StudentID)).ToList();
            //not in
            var in4 = db.Queryable<Student>().Where(it => !array.Contains(it.StudentID)).ToList();
            //where
            var getByWhere = db.Queryable<Student>().Where(it => it.StudentID == "000136bf-f968-4a59-9091-bae8ebca42fb" || it.StudentName == "陳麗").ToList();
            //SqlFunc
            var getByFuns = db.Queryable<Student>().Where(it => SqlFunc.IsNullOrEmpty(it.StudentName)).ToList();
            //between and 
            var between = db.Queryable<Student>().Where(it => SqlFunc.Between(it.CreateTime, DateTime.Now.AddDays(-10), DateTime.Now)).ToList();
            //排序
            var getAllOrder = db.Queryable<Student>().Take(100).OrderBy(it => it.CreateTime).ToList(); //默認為ASC排序
            //組合排序
            var data = db.Queryable<Student>()
                .OrderBy(it => it.StudentName, OrderByType.Asc)
                .OrderBy(it => it.CreateTime, OrderByType.Desc)
                .ToList();

            //是否存在 any
            var isAny = db.Queryable<Student>().Where(it => it.StudentName == "張龍").Any();
            var isAny2 = db.Queryable<Student>().Any(it => it.StudentSex == "");
            //獲取同一天的記錄
             var getTodayList = db.Queryable<Student>().Where(it => SqlFunc.DateIsSame(it.CreateTime, DateTime.Now)).ToList();

            Console.ReadLine();
        }
View Code

 多表查詢:

    class Program
    {
        static SugarDbContext sugar = new SugarDbContext();
        static void Main(string[] args)
        {
            var db = sugar.Db;
            var list = db.Queryable<Student, StudentGrad>((st, sc) => new object[] {
                        JoinType.Inner,st.GradID==sc.GradID})
                        .Select((st, sc) => new { StudentName = st.StudentName, GradName = sc.GradName }).ToList();
            var list2 = db.Queryable<Student, StudentGrad>((st, sc) => new object[] {
                        JoinType.Inner,st.GradID==sc.GradID})
                      .Select((st, sc) => new ViewModel { StudentName = st.StudentName, GradName = sc.GradName }).ToList();

            ///3張表關聯查詢
            //var list3 = db.Queryable<Student, School, Student>((st, sc, st2) => new object[] {
            //  JoinType.Left,st.SchoolId==sc.Id,
            //  JoinType.Left,st.SchoolId==st2.Id
            //})
            //         .Where((st, sc, st2) => st2.Id == 1 || sc.Id == 1 || st.Id == 1)
            //         .OrderBy((sc) => sc.Id)
            //         .OrderBy((st, sc) => st.Name, OrderByType.Desc)
            //         .Select((st, sc, st2) => new { st = st, sc = sc }).ToList();

            ///分頁查詢
            var pageIndex = 1;
            var pageSize = 10;
            var list4 = db.Queryable<Student, StudentGrad>((st, sc) => new object[] {
              JoinType.Left,st.GradID==sc.GradID
            }).Select((st, sc) => new ViewModel { StudentName = st.StudentName, GradName = sc.GradName })
           .ToPageList(pageIndex, pageSize);

            foreach(var item in list4)
            {
                Console.WriteLine(item.GradName + item.StudentName);
            }       

            ///五張表關聯查詢
            //var list2 = db.Queryable<Student, School, Student, Student, Student>((st, sc, st2, st3, st4) => new object[] {
            //  JoinType.Left,st.SchoolId==sc.Id,
            //  JoinType.Left,st.Id==st2.Id,
            //  JoinType.Left,st.Id==st3.Id,
            //  JoinType.Left,st.Id==st4.Id
            //}).Where((st, sc) => sc.Id == 1)
            // .Select((st, sc, st2, st3, st4) => new { id = st.Id, name = st.Name, st4 = st4 }).ToList();

            ///二個Queryable的Join(4.6.0.9)
            var q1 = db.Queryable<Student>();
            var q2 = db.Queryable<StudentGrad>();
            var innerJoinList = db.Queryable(q1, q2, (j1, j2) => j1.GradID == j2.GradID).Select((j1, j2) => j1).ToList();//inner join

            ///多表查詢的簡化 默認為inner join 
            var list5 = db.Queryable<Student, StudentGrad>((st, sc) => st.GradID == sc.GradID).Select((st, sc) => new ViewModel { StudentName= st.StudentName, GradName= sc.GradName}).ToList();

            ///3表查詢
            //var list6 = db.Queryable<Student, School, School>((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id)
            //    .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToList();

            ///3表查詢分頁
            //var list7 = db.Queryable<Student, School, School>((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id)
            //.Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1, 2);


            ///qlFunc.Subqueryable 子查詢
//            var getAll = db.Queryable<Student, School>((st, sc) => new object[] {
//JoinType.Left,st.Id==sc.Id})
//.Where(st => st.Id == SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Select(s => s.Id))
//.ToList();

//            //生成的MYSQL語句,如果是SqlServer就是TOP 1
//            SELECT `st`.`ID`,`st`.`SchoolId`,`st`.`Name`,`st`.`CreateTime` 
//     FROM `STudent` st Left JOIN `School` sc ON( `st`.`ID` = `sc`.`Id` )  
//      WHERE( `st`.`ID` = (SELECT `Id` FROM `School` WHERE( `Id` = `st`.`ID` ) limit 0, 1))
            Console.ReadLine();
        }
    }


    class ViewModel
    {   
        public string StudentName { get; set; }  
        public string GradName { get; set; }
    }
View Code

 查詢函數 SqlFunc.

    class Program
    {
        static SugarDbContext sugar = new SugarDbContext();
        static void Main(string[] args)
        {
            var db = sugar.Db;

            ///SqlFunc.ToLower 小寫
            var slst = db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.StudentName) == SqlFunc.ToLower("JACK")).ToList();

            ///qlFunc.ToUpper 大寫
            var slst_2 = db.Queryable<Student>().Where(it => SqlFunc.ToUpper(it.StudentName) == "JACK").ToList();
            var slst_21 = db.Queryable<Student>().Where(it => it.StudentName == "JACK").ToList();

            ///三元判段 ,相當於 it.id==1?1:2
            var slst_3 = db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.StudentName) == SqlFunc.ToLower("JACK")).Select(A =>new StuModel { StudentName= SqlFunc.IIF(A.StudentName == "JACK", "傑克", "其他") , StuSex=A.StudentSex} ).ToList();

            ///if else end 4.6.0.1
            var slst_4 = db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.StudentName).Contains("tom") ).Select(A => new StuModel { StudentName = SqlFunc.IF(A.StudentName=="tom1")
             .Return("大湯姆")
             .ElseIF(A.StudentName== "tom2")
             .Return("中湯姆").End("小湯姆"), StuSex = A.StudentSex }).ToList();
            foreach(var item in slst_4)
            {
                Console.WriteLine(item.StudentName); 
            }
            ///ISNULL 查詢
            ///IsNullOrEmpty 判段是NULL或者空
            ///SqlFunc.HasValue 判段不是NULL並且不是空
            ///SqlFunc.HasNumber 判段大於0並且不等於NULL
            ///SqlFunc.Trim 去空格
            var slst_5 = db.Queryable<Student>().Where(A => A.StudentID == "00013a00-9067-40c1-be2a-a06fea47c632").Select(A => new StuModel { StudentName = SqlFunc.IsNull(A.StudentName, "暫無姓名"), StuSex = A.StudentSex }).ToList();
            foreach (var item in slst_5)
            {
                Console.WriteLine(item.StudentName);
            }
            ///獲取數據庫時間 SqlFunc.GetDate()
            //var tim = SqlFunc.GetDate();//會報錯
            var date = DateTime.Now.AddDays(-10);
            var slst_6 = db.Queryable<Student>().Where(A => SqlFunc.Between(A.CreateTime, date, SqlFunc.GetDate())).ToList();
            Console.WriteLine(slst_6.Count);
            ///Contains 模糊查詢 like %@p%
            ///StartsWith 模糊查詢 like %@p%
            ///EndsWith 模糊查詢 like %@p%
            ///
            var slst_7 = db.Queryable<Student>().Where(A =>A.StudentName.EndsWith("") ).ToList();
            ///等於 SqlFunc.Equals(object thisValue, object parameterValue)
            ///是否是同一天 SqlFunc.DateIsSame(DateTime date1, DateTime date2)
            ///是否是同一時間 (dataType 可以是年、月、天、小時、分鍾、秒和毫秒) SqlFunc.DateIsSame(DateTime date1, DateTime date2, DateType dataType)
            ///在當前時間加一定時間(dataType 可以是年、月、天、小時、分鍾、秒和毫秒) SqlFunc.DateAdd(DateTime date, int addValue, DateType dataType)
            ///在當前時間加N天 SqlFunc.DateAdd(DateTime date, int addValue)
            ///獲取當前時間的年、月、天、小時、分鍾、秒或者毫秒 SqlFunc.DateValue(DateTime date, DateType dataType)
            ///范圍判段 SqlFunc.Between(object value, object start, object end)
            ///
            var slst_8 = db.Queryable<Student>().Where(A =>SqlFunc.DateAdd(Convert.ToDateTime(A.CreateTime),1,DateType.Day)>Convert.ToDateTime("2020-10-23")).ToList();
            ///類型轉換
            ///
            /*
            SqlFunc.ToInt32(object value) 
            SqlFunc.ToInt64(object value)
            SqlFunc.ToDate(object value) 
            SqlFunc.ToString(object value) 
            SqlFunc.ToDecimal(object value) 
            SqlFunc.ToGuid(object value) 
            SqlFunc.ToDouble(object value) 
            SqlFunc.ToBool(object value)
            */
            ///
            ///截取字符串 SqlFunc.Substring(object value, int index, int length)
            ///替換字符串 SqlFunc.Replace(object value, string oldChar, string newChar)
            ///獲取字符串長度 SqlFunc.Length(object value)
            ///

            ///聚合函數
            /*
             SqlFunc.AggregateSum<TResult>(TResult thisValue) 
             SqlFunc.AggregateAvg<TResult>(TResult thisValue)
             SqlFunc.AggregateMin(TResult thisValue) 
             SqlFunc.AggregateMax<TResult>(TResult thisValue) 
             SqlFunc.AggregateCount<TResult>(TResult thisValue)
             */
            ///
            var slst_9 = db.Queryable<Student>().Select(A => SqlFunc.AggregateMax<DateTime?>(A.CreateTime)).ToList();
            var slst_91 = db.Queryable<Student>().Select(A => SqlFunc.AggregateMax(A.CreateTime)).ToList();
            var slst_10 = db.Queryable<Student>().Select(A => SqlFunc.AggregateMin(A.CreateTime)).ToList();

            Console.ReadLine();
        }
    }


    class ViewModel
    {   
        public string StudentName { get; set; }  
        public string GradName { get; set; }
    }
    class StuModel
    {
        public string StudentName { get; set; }
        public string StuSex { get; set; }
    }
View Code

 動態查詢。where 拼接 ,組合拼接

using SqlSugar;
using Sugar.Enties;
using SugarContext;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace SugarCore
{
    class Program
    {
        static SugarDbContext sugar = new SugarDbContext();
        static void Main(string[] args)
        {
            var db = sugar.Db;
            var queryable = db.Queryable<Student>();
            //拼接會比EF方便些,不像EF需要queryable+=
            queryable.Where(it => it.StudentName.Contains(""));
            queryable.Where(it => it.StudentSex == "");
            //防止queryable相互影響我們用clone解決
            var StudentName = queryable.Clone().Select(it => it.StudentName).First();
            /////正確答案是兩條數據 如果去掉Clone,受上面一條影響,只會有一條數據
            var list = queryable.Clone().ToList();//正確答案是兩條數據 如果去掉Clone,受上面一條影響,只會有一條數據
            ///案例1: WhereIF函數
            ///根據條件判段是否執行過濾,我們可以用WhereIf來實現,true執行過濾,false則不執行
            ///
            var a = "";
            var b = "";
            var c = "";
            ///陳性女同學一個
            var list2 = db.Queryable<Student>()
    .WhereIF(!string.IsNullOrEmpty(a), it => it.StudentName.StartsWith(a))
    .WhereIF(!string.IsNullOrEmpty(b), it => it.StudentName.EndsWith(b))
    .WhereIF(!string.IsNullOrEmpty(c), it => it.StudentSex == c).ToList();
            //

            ///所有叫陳飛的童鞋9人   string.IsNullOrEmpty(c) 這個語句不會執行
            var list3 = db.Queryable<Student>()
    .WhereIF(!string.IsNullOrEmpty(a), it => it.StudentName.StartsWith(a))
    .WhereIF(!string.IsNullOrEmpty(b), it => it.StudentName.EndsWith(b))
    .WhereIF(string.IsNullOrEmpty(c), it => it.StudentName == c).ToList();


            ///
            /*
             案例2.:MergeTable 函數 4.4
             是將多表查詢的結果Select里的內容變成一張表, 如果是多表查詢的時候,我們無論是使用 where 還是 orderBy 都需要加別名,這樣我們就不能實現動態排序,因為我不知道別名叫什么, 可以用MergeTable解決這個問題
             */
            ///多表查詢方式
            var pageJoin = db.Queryable<Student, StudentGrad>((st, sc) => new object[]
                {
                  JoinType.Inner, st.GradID == sc.GradID
                })
                .Where(st => st.StudentName.EndsWith(""))//別名是st
                .OrderBy("st.StudentName asc")//別名是sc
                .Select((st, sc) => new { StudentName = st.StudentName, gradeName = sc.GradName })
                .ToList();

            ///等同於MergeTable 方式
            ///
            var pageJoin_2 = db.Queryable<Student, StudentGrad>((st, sc) => new object[]
                                {
                                    JoinType.Inner,st.GradID==sc.GradID
                                })
                                .Select((st, sc) => new
                                {
                                    StudentName = st.StudentName,
                                    gradeName = sc.GradName
                                })
                                .MergeTable()
                                .Where(A => A.StudentName.EndsWith("")).OrderBy("StudentName asc").ToList();//別名不限


            ///案例3: SqlQueryable 4.5.2.5 , 可以方便的把SQL變成表來操作 直接執行SQL語句
            ///
            var t12 = db.SqlQueryable<Student>("select * from student").ToPageList(1, 2);

            ///案例4: 將表單組裝成 List<ConditionalModel>實現查詢 4.5.9
            ///查詢女生中 帶有 飛 子的同學
            List<IConditionalModel> conModels = new List<IConditionalModel>();
            conModels.Add(new ConditionalModel() { FieldName = "StudentSex", ConditionalType = ConditionalType.Equal, FieldValue = "" });
            conModels.Add(new ConditionalModel() { FieldName = "StudentName", ConditionalType = ConditionalType.Like, FieldValue = "" });
            var student = db.Queryable<Student>().Where(conModels).ToList();

            ///
            //4.6.4.4 版本支持了 復雜的OR 
            // and StudentSex='女' And (StudentName='陳芬' or StudentName='王芬' Or StudentName='李芬') 
            List<IConditionalModel> conModels__22 = new List<IConditionalModel>();
            conModels__22.Add(new ConditionalModel() { FieldName = "StudentSex", ConditionalType = ConditionalType.Equal, FieldValue = "" });
            conModels__22.Add(new ConditionalCollections()
            {
                ConditionalList =
            new List<KeyValuePair<WhereType, SqlSugar.ConditionalModel>>()
            {
    new  KeyValuePair<WhereType, ConditionalModel>
    ( WhereType.And , //And
    new ConditionalModel() { FieldName = "StudentName", ConditionalType = ConditionalType.Equal, FieldValue = "陳芬" }),
    new  KeyValuePair<WhereType, ConditionalModel>
    (WhereType.Or,
    new ConditionalModel() { FieldName = "StudentName", ConditionalType = ConditionalType.Equal, FieldValue = "王芬" }),
    new  KeyValuePair<WhereType, ConditionalModel>
    ( WhereType.Or,
    new ConditionalModel() { FieldName = "StudentName", ConditionalType = ConditionalType.Equal, FieldValue = "李芬" })
            }
            });
            var studentResult = db.Queryable<Student>().Where(conModels__22).ToList();


            ///案例5: 拼接拉姆達 4.5.9.8
            ///
            var exp = Expressionable.Create<Student>()
      .OrIF(1 == 1, it => it.StudentSex == "")
      .And(it => it.StudentName.Contains(""))
      .AndIF(2 == 3, it => SqlFunc.IsNullOrEmpty(it.StudentName)) //此where 不執行
      .Or(it => it.StudentName.Contains("")).ToExpression();//拼接表達式

            var list55 = db.Queryable<Student>().Where(exp).ToList();


            ///Queryable是支持字符串與拉姆達混用或者純字符串拼接模式,可以滿足復雜的一些需求
            ///復雜動態 表達式和SQL子查詢混合模式
            ///
            ////例子1:

            ////    var queryable = db.Queryable<Student>("t");

            ////    queryable.Where("t.id in (select id from xxx)");

            ////    queryable.Where(it => it.Id == 1);

            ////    //更多操作拼接qureyable  

            ////    var result = queryable.Select(@"
            ////          id,
            ////          name,
            ////          (select name form school where shoolid=t.id) as schoolName
            ////           ").ToList();


            ////例子2:

            ////    dynamic join3 = db.Queryable("Student", "st")
            ////            .AddJoinInfo("School", "sh", "sh.id=st.schoolid")
            ////            .Where("st.id>@id")
            ////            .AddParameters(new { id = 1 })
            ////            .Select("st.*").ToList(); //也可以Select<T>(“*”).ToList()返回實體集合


            ////例子3:

            ////    var list = db.Queryable<Student>().
            ////                    Select(it => new Student()
            ////                    {
            ////                        Name = it.Name,
            ////                        Id = SqlFunc.MappingColumn(it.Id, "(select top 1 id from school)") // 動態子查詢
            ////        }).ToList();



            ///安全拼SQL
            ///安全拼SQL 安全拼SQL 安全拼SQL 安全拼SQL 安全拼SQL 安全拼SQL 安全拼SQL 安全拼SQL 安全拼SQL
            ////            安全拼SQL
            ////使用參數化過濾

            ////private static void Where()
            ////            {
            ////                var db = GetInstance();
            ////                string value = "'jack';drop table Student";
            ////                var list = db.Queryable<Student>().Where("name=@name", new { name = value }).ToList();
            ////                //沒有發生任何事情
            ////            }


            ////            字段是無法用參數化實現的,我們就可以采用這種方式過濾

            ////private static void OrderBy()
            ////            {
            ////                var db = GetInstance();
            ////                try
            ////                {
            ////                    var propertyName = "Id'"; //類中的屬性的名稱
            ////                    var dbColumnName = db.EntityProvider.GetDbColumnName<Student>(propertyName);
            ////                    var list2 = db.Queryable<Student>().OrderBy(dbColumnName).ToList();
            ////                }
            ////                catch (Exception ex)
            ////                {
            ////                    Console.WriteLine(ex.Message);
            ////                }
            ////            }
            Console.ReadLine();
        }
    }


    class ViewModel
    {   
        public string StudentName { get; set; }  
        public string GradName { get; set; }
    }
    class StuModel
    {
        public string StudentName { get; set; }
        public string StuSex { get; set; }
    }
}
View Code

 分組查詢【自己沒經過測試】

分組查詢




1.分組查詢

var group = db.Queryable<Student>().GroupBy(it => it.Id)
    .Having(it => SqlFunc.AggregateCount(it.Id) > 10)
    .Select(it => new { id = SqlFunc.AggregateCount(it.Id) }).ToList();
多個GroupBy寫法如下

var group = db.Queryable<Student>().GroupBy(it => it.Id).GroupBy(it => it.Type)
    .Having(it => SqlFunc.AggregateCount(it.Id) > 10)
    .Select(it => new { id = SqlFunc.AggregateCount(it.Id) }).ToList();
還可以

.GroupBy(it => new {it.Id,it.Type})





2.簡單去重 


var list3 = db.Queryable<Student>()
.GroupBy(it => new { it.Id, it.Name }).Select(it=>new{ it.id,it.Name}).ToList();
// 性能優於 select distinct id,name from student所以我暫不支持distinct去重,結果是一樣的






3.去重並且返回所有列(分組第一條)

group by只能返回特定列,PartitionBy可以返回所有列

var list3 = db.Queryable<Student>()
.PartitionBy(it => new { it.Id, it.Name }).Take(1).ToList();
View Code

分頁查詢

var db = GetInstance();
var pageIndex = 1;
var pageSize = 2;
var totalCount = 0;




單表分頁

var page = db.Queryable<Student>().OrderBy(it => it.Id).ToPageList(pageIndex, pageSize, ref totalCount);


多表分頁

var pageJoin = db.Queryable<Student, School>((st, sc) => new object[] {
    JoinType.Left,st.SchoolId==sc.Id
}).ToPageList(pageIndex, pageSize, ref totalCount);


取前5條

var top5 = db.Queryable<Student>().Take(5).ToList();


取前5條之后的所有數據

var skip5 = db.Queryable<Student>().Skip(5).ToList();




注意:SqlServer版本底層采用的是Rownumber分頁,在排序字段有索引的情況下性能是最好的分頁,優於12分頁和TOP分頁,

RowNumber分頁是頁碼越小性能越快符合多數人的使用習慣,如果追求極限性能 當前碼數 大於總頁數的一半時可以采用倒序分頁法實現對大頁碼的優化同樣達到小頁碼的性能。

參考代碼:

  
 //常規寫法
 db.Queryable<Student>().OrderBy(it=>it.Id).ToPageList(pageIndex,pageSize);
  
  
 //針對rowNumber分頁的優化寫法,該寫法可以達到分頁最高性能,非對性能要求過高的可以不用這么寫
 var Tempdb=db.Queryable<Student>();
 int count = Tempdb.Count();
                var Skip = (R.Page - 1) * R.PageCount;
                var Take = R.PageCount;
                if (R.Page*R.PageCount > P.Count / 2)//頁碼大於一半用倒序
                {
                    Tempdb.OrderBy(x => x.ID, OrderByType.Desc);
                    var Mod = P.Count % R.PageCount;
                    var Page = (int)Math.Ceiling((Decimal)P.Count / R.PageCount);
                    if (R.Page * R.PageCount >= P.Count)
                    {
                        Skip = 0; Take = Mod == 0 ? R.PageCount : Mod;
                    }
                    else
                    {
                        Skip = (Page - R.Page - 1) * R.PageCount + Mod;
                    }
                }
                else
                {
                    Tempdb.OrderBy(x => x.ID);//升序
                }
                Tempdb.Skip(Skip);
                Tempdb.Take(Take);
 var list=Tempdb.ToList();
View Code

事務

事務
重要的事情說三遍:

事務只能在同一個SqlSugarClient對象有效,事務只能在同一個SqlSugarClient對象有效,事務只能在同一個SqlSugarClient對象有效,跨SqlSugarClient對象請用分布式事務



MySql特殊的庫或表不支持事務,所以如果是用MYSQL的朋友需要注意了



正確用法:

用法1: 無數據返回只返回狀態

var result = db.Ado.UseTran(() =>
{
    var beginCount = db.Queryable<Student>().Count();
    db.Ado.ExecuteCommand("delete student");
    //throw new Exception("error haha"); 測試代碼
});
 
// result.ErrorException
// result.IsSuccess


用法2:返回數據並且返回狀態

var result2 = db.Ado.UseTran<List<Student>>(() =>
{
    return db.Queryable<Student>().ToList();
});
// result.ErrorException
// result.IsSuccess
// result.Data


用法3: 使用try catch來處理事務,用這種方式事務一定要加try catch回滾不然會鎖表,在操作就卡死

try
{
 db.Ado.BeginTran();
 操作
 db.Ado.CommitTran();
}
catch (Exception ex)
{
 db.Ado.RollbackTran();
 throw ex;
}


錯誤用法,創建了3個db對象

{9LGEVS(WE_8_6WJG4NO]3L.png

正確寫法

var db=GetAll(); //GetAll是獲取新的Db實例的方法
db.Ado.SqlQuery<T>(sql)




跨類事務方案

http://www.codeisbug.com/Doc/8/1158







4.7 異步事務的支持

因為Async方法在事務中無效所以對於多個SqlSugar方法進行事務操作並且能夠實現異步增加了該功能

            //無返回值只返回狀態
            var asyncResult = db.Ado.UseTranAsync(() =>
            {
 
                var beginCount = db.Queryable<Student>().ToList();
                db.Ado.ExecuteCommand("delete student");
                var endCount = db.Queryable<Student>().Count();
                throw new Exception("error haha");
            });
            asyncResult.Wait();
            var asyncCount = db.Queryable<Student>().Count();
 
            //有返回值和狀態
            var asyncResult2 = db.Ado.UseTranAsync<List<Student>>(() =>
            {
                return db.Queryable<Student>().ToList();
            });
            asyncResult2.Wait();




和EF一樣的事務用法

http://www.codeisbug.com/Doc/8/1174
View Code

執行SQL

執行SQL
Sqlqueryable

sqlueryable只支持查詢操作,並且支持拉姆達分頁



var t12 = db.SqlQueryable<Student>("select * from student").Where(it=>it.id>0).ToPageList(1, 2);



var t12 = db.SqlQueryable<dynamic>("select * from student").ToPageList(1, 2);//返回動態類型





Ado方法

1.重載:object parameters

var dt=db.Ado.SqlQuery<Student>("select * from table where id=@id and name=@name",new {id=1,name="a"});
var dt=db.Ado.SqlQuery<Student>("select * from table where id=@id and name=@name",字典);
2.重載: List<SugarParameter> parameters

var dt=db.Ado.GetDataTable("select * from table where id=@id and name=@name",new List<SugarParameter>(){
  new SugarParameter("@id",1),
  new SugarParameter("@name",2)
});
3.重載:params SugarParameter[] parameters

var dt=db.Ado.GetDataTable("select * from table");
 
var dt=db.Ado.GetDataTable("select * from table where id=@id",new SugarParameter("@id",1));
 
var dt=db.Ado.GetDataTable("select * from table where id=@id and name=@name",new SugarParameter []{
  new SugarParameter("@id",1),
  new SugarParameter("@name",2)
});

全部函數


1.獲取DataTable (如是.Net Core版本, DataTable是Sqlsugar自定義的DataTable, 因為以前的Core 1.x不支持DataTable, 后遺症, 效率不用擔心)

db.Ado.GetDataTable(string sql, object parameters);
db.Ado.GetDataTable(string sql, params SugarParameter[] parameters);
db.Ado.GetDataTable(string sql, List<SugarParameter> parameters);


2.獲取DataSet

db.Ado.GetDataSetAll(string sql, object parameters);
db.Ado.GetDataSetAll(string sql, params SugarParameter[] parameters);
db.Ado.GetDataSetAll(string sql, List<SugarParameter> parameters);


3.獲取DataReader

db.Ado.GetDataReader(string sql, object parameters);
db.Ado.GetDataReader(string sql, params SugarParameter[] parameters);
db.Ado.GetDataReader(string sql, List<SugarParameter> parameters);


4.獲取首行首列返回object類型

db.Ado.GetScalar(string sql, object parameters);
db.Ado.GetScalar(string sql, params SugarParameter[] parameters);
db.Ado.GetScalar(string sql, List<SugarParameter> parameters);


5.執行數據庫返回受影響行數

int ExecuteCommand(string sql, object parameters);
int ExecuteCommand(string sql, params SugarParameter[] parameters);
int ExecuteCommand(string sql, List<SugarParameter> parameters);


6.獲取首行首列更多重載

//以下為返回string
string GetString(string sql, object parameters);
string GetString(string sql, params SugarParameter[] parameters);
string GetString(string sql, List<SugarParameter> parameters);
 
//返回int
int GetInt(string sql, object pars);
int GetInt(string sql, params SugarParameter[] parameters);
int GetInt(string sql, List<SugarParameter> parameters);
 
//返回double
db.Ado.GetDouble(string sql, object parameters);
db.Ado.GetDouble(string sql, params SugarParameter[] parameters);
db.Ado.GetDouble(string sql, List<SugarParameter> parameters);
 
//返回decimal
db.Ado.GetDecimal(string sql, object parameters);
db.Ado.GetDecimal(string sql, params SugarParameter[] parameters);
db.Ado.GetDecimal(string sql, List<SugarParameter> parameters);
 
//返回DateTime
db.Ado.GetDateTime(string sql, object parameters);
db.Ado.GetDateTime(string sql, params SugarParameter[] parameters);
db.Ado.GetDateTime(string sql, List<SugarParameter> parameters);


7.查詢並返回List<T>

db.Ado.SqlQuery<T>(string sql, object whereObj = null);
db.Ado.SqlQuery<T>(string sql, params SugarParameter[] parameters);
db.Ado.SqlQuery<T>(string sql, List<SugarParameter> parameters);


8.查詢返回單條記錄

db.Ado.SqlQuerySingle<T>(string sql, object whereObj = null);
db.Ado.SqlQuerySingle<T>(string sql, params SugarParameter[] parameters);
db.Ado.SqlQuerySingle<T>(string sql, List<SugarParameter> parameters);


9.查詢返回動態類型(該類型為Newtonsoft.Json里面的JObject類型, 使用方法自行百度)

db.Ado.SqlQueryDynamic(string sql, object whereObj = null);
db.Ado.SqlQueryDynamic(string sql, params SugarParameter[] parameters);
db.Ado.SqlQueryDynamic(string sql, List<SugarParameter> parameters);
View Code

存儲過程

存儲過程


CommandType.Text方式

也就是SQL腳本的方式,這種方式是不能直接用存儲過程名字去調用的,需要這樣寫

db.Ado.GetInt("exec spName @p1",new {p=1})


CommandType.StoredProcedure 方式

4.5.02版本支持

var dt2 = db.Ado.UseStoredProcedure().GetDataTable("sp_school",new{name="張三",age=0});//  GetInt SqlQuery<T>  等等都可以用
 
//支持output
var nameP= new SugarParameter("@name", "張三");
var ageP= new SugarParameter("@age", null, true);//isOutput=true
var dt2 = db.Ado.UseStoredProcedure().GetDataTable("sp_school",nameP,ageP);
//ageP.value可以拿到返回值


Oracle游標

 parameter.IsRefCursor =true;







我們還可以用 GetParameters 來簡化參數操作

 string p=null;
 SugarParameter [] pars =db.Ado.GetParameters(new{p=1,p2=p});
 var p2= pars[1].Direction=ParameterDirection.Output;
View Code

插入

插入


注意:

          Oracle反回自增列 在字段特性SugarColumn 可以設置序列名稱

          SqlSever插量插入慢一般是建表語句帶有Wtih(索引設置)引起的,把With刪掉會很快





插入並返回受影響行數用ExecuteCommand 

var t2 = db.Insertable(insertObj).ExecuteCommand();


插入並返回自增列用ExecuteReutrnIdentity

int t30 = db.Insertable(insertObj).ExecuteReturnIdentity();
long t31 = db.Insertable(insertObj).ExecuteReturnBigIdentity(); //4.5.0.2 +  long


4.2.3插入並返回實體 ,  只是自identity 添加到 參數的實體里面並返回,沒有查2次庫,所以有些默認值什么的變動是取不到的你們需要手動進行2次查詢獲取

var t3 = db.Insertable(insertObj).ExecuteReturnEntity();


4.5.0.2 插入並返回bool, 並將identity賦值到實體

var t3 = db.Insertable(insertObj).ExecuteCommandIdentityIntoEntity();


只插入列 Name和SchoolId

var t4 = db.Insertable(insertObj).InsertColumns(it => new { it.Name, it.SchoolId }).ExecuteReturnIdentity();


不插入列 Name和TestId

var t5 = db.Insertable(insertObj).IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteReturnIdentity();




根據條件指定不插入列

var t6 = db.Insertable(insertObj).IgnoreColumns(it => it == "Name" || it == "TestId").ExecuteReturnIdentity();


List中所有列不插入

var t61 = db.Insertable(updateObj)
.IgnoreColumns(it => list.Contains(it)  ).ExecuteCommand();


使用鎖

var t8 = db.Insertable(insertObj).With(SqlWith.UpdLock).ExecuteCommand();


可以設置NULL列不插入和是否強制插入自增列

var t9 = db.Insertable(insertObj2)
.Where(true/* Is no insert null */, true/*off identity*/)
.ExecuteCommand();


批量插入(性能很快不用操心)

var insertObjs = new List<Student>();
var s9 = db.Insertable(insertObjs.ToArray()).ExecuteCommand();
//注意 : SqlSever 建表語句帶有Wtih(設置),如果設置不合理,可能會引起慢,把With刪掉就會很快


4.2.2 匿名對象和字典的支持

var t12 = db.Insertable<Student>(new { Name = "a" }).ExecuteCommand();
//INSERT INTO [STudent]  ([Name]) VALUES ('a') ;SELECT SCOPE_IDENTITY();
 var t13 = db.Insertable<Student>(new Dictionary<string, object>() {{ "name","a"} }).ExecuteCommand();
//INSERT INTO [STudent]  ([Name]) VALUES ('a') ;SELECT SCOPE_IDENTITY();


4.6.4.8支持了不加泛型的字典

var dt = new Dictionary<string, object>();
dt.Add("name", "1");
var t66 = db.Insertable(dt).AS("student").ExecuteReturnIdentity();


4.6.1 插入數據庫默認值

我們只要在實體上加上

[SugarColumn(IsOnlyIgnoreInsert=true)]
 public DateTime CreateTime { get; set; }


將A表數據插入B表

db.Insertable(db.Queryable<A>().Select<B>().ToList()).ExecuteCommand();
View Code

刪除

刪除
根據實體刪除(實體內主鍵一定要有值)

var t0 = db.Deleteable<Student>().Where(new Student() { Id = 1 }).ExecuteCommand();


根據實體集刪除

var  t1 = db.Deleteable<Student>().Where(new List<Student>() { new Student() { Id = 1 } }).ExecuteCommand();


使用鎖

var t2 = db.Deleteable<Student>().With(SqlWith.RowLock).ExecuteCommand();




根據主鍵刪除

var t3 = db.Deleteable<Student>().In(1).ExecuteCommand();


根據主鍵批量刪除

var t4 = db.Deleteable<Student>().In(new int[] { 1, 2 }).ExecuteCommand();


根據非主鍵批量刪除4.9

var t4 = db.Deleteable<Student>().In(it=>it.SchoolId,new int[] { 1, 2 }).ExecuteCommand();




根據表達式刪除

var t5 = db.Deleteable<Student>().Where(it => it.Id == 1).ExecuteCommand();//刪除等於1的
 
//批量刪除非主鍵
list<int> list=new list<int>(){1,3};
var t5 = db.Deleteable<Student>().Where(it => !list.Contains(it.Id) ).ExecuteCommand();




4.1.0.6 版本之后可以對上面的語法進行優化

db.Deleteable<Student>(1).ExecuteCommand();
db.Deleteable<Student>(it=>it.id==1).ExecuteCommand();
db.Deleteable<Student>(new int[]{1,2,3}).ExecuteCommand();
db.Deleteable<Student>(實體).ExecuteCommand();
View Code

更新

SqlSugar更新分為2大類寫法,1種是傳實體對象的方式 這種是以實體對象為核心進行更新,不傳實體對象這種是以表達式為核心進行更新


//傳實體對象寫法(支持批量對象)
db.Updateable(updateObj) 
 
//不傳實體對象寫法
db.Updateable<T>()




傳對象的用法



根據實體更新(主鍵要有值,主鍵是更新條件)

var t1 = db.Updateable(updateObj).ExecuteCommand(); //這種方式會以主鍵為條件


4.2.3添加了WhereColumns 雖然XId不是主鍵但是 XId作為更新條件


var t1 = db.Updateable(updateObj).WhereColumns(it=>new{it.XId}).ExecuteCommand();//單列可以用 it=>it.XId
 
//需要注意 當WhereColumns和UpdateColumns一起用時,需要把wherecolumns中的列加到UpdateColumns中
var update = db.Updateable(updateObj).UpdateColumns(s => new { s.RowStatus,s.Id }).WhereColumns(it => new { it.Id });


只更新實體里面的Name列(主鍵要有值,主鍵是更新條件)

var t3 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name }).ExecuteCommand();


更新 Name和 TestId 以外的所有列 (主鍵要有值,主鍵是更新條件)

var t4 = db.Updateable(updateObj)
.IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteCommand();


更新NAME 以外的所有列

var t5 = db.Updateable(updateObj)
.IgnoreColumns(it => it=="name" ).ExecuteCommand(); //name列不更新
 
 
var t5 = db.Updateable(updateObj)
.IgnoreColumns(it => list.Contains(it)  ).ExecuteCommand(); //List中所有列不更新


使用鎖

var t6 = db.Updateable(updateObj).With(SqlWith.UpdLock).ExecuteCommand();


批量更新(主鍵要有值,主鍵是更新條件)

List<Students> list=GetList();
var t7 = db.Updateable(list).ExecuteCommand();


實體更新,並且給Name重新賦值 ,其它列也會更新

var t8 = db.Updateable(updateObj)
.ReSetValue(it => it.Name == (it.Name + 1)).ExecuteCommand();


只更新Name並且 Name的值等於Name+1, 如果updateObj值為NULL一定要加WHERE才可以

//寫法1
var t8 = db.Updateable(updateObj)
.UpdateColumns(it=>new {it.Name}).ReSetValue(it => it.Name == (it.Name + 1)).ExecuteCommand();
第一種updateable()有參數的,下面二種是沒參數的注意下區別



更新實體,更新條件是根據表達式

var t9 = db.Updateable(updateObj).Where(it => it.Id == 1).ExecuteCommand();


是NULL的列不更新

db.Updateable(updateObj).IgnoreColumns(ignoreAllNullColumns:true).ExecuteCommand();


4.6.4.8 版本支持了不需要泛型的字典

//如果initKey.Systemtable方是寫法
var dt = new Dictionary<string,object>();
dt.Add("id", 1);
dt.Add("name", "1");
var t66 = db.Updateable(dt).AS("student").ExecuteCommand();
//UPDATE STUDENT  SET  NAME=@name  WHERE ID=@ID
 
//如果initkey.Attribute方式是拿不出主鍵信息的需要寫成這樣
var dt = new Dictionary<string,object>();
dt.Add("id", 1);
dt.Add("name", "1");
var t66 = db.Updateable(dt).AS("student").WhereColumns("id").With(SqlWith.UpdLock).ExecuteCommand()
//沒有WhereColumns(string)去下載最新的
 
//也支持List<Dictionary<string,object>>


4.2.2 更新 匿名對象和字典的支持

 var t13 = db.Updateable<Student>(new { Name = "a", id=1 }).ExecuteCommand();
 //UPDATE [STudent]  SET [Name]='a' WHERE [Id]=1
 var t14 = db.Updateable<Student>(new Dictionary<string, object>() { { "id", 1 }, { "name", "a" } }).ExecuteCommand();
 //UPDATE [STudent]  SET [Name]='a' WHERE [Id]=1




不傳對象的用法

根據表達式中的列更新   ,只更新 Name和CreateTime 條件是id=11,比較常用

//正確寫法
 var t10 = db.Updateable<Student>()
.UpdateColumns(it => new Student() { Name = "a", CreateTime = DateTime.Now })
.Where(it => it.Id == 11).ExecuteCommand();
 
//錯誤寫法
var st=new Student() { Name = "a", CreateTime = DateTime.Now };
var t10 = db.Updateable<Student>()
.UpdateColumns(it => st)
.Where(it => it.Id == 11).ExecuteCommand();


別名表

db.Updateable<School>().AS("Student")
.UpdateColumns(it => new School() { Name = "jack" })
.Where(it => it.Id == 1).ExecuteCommand();
//Update Student set Name='jack' Where Id=1


4.6.0.7 聯表更新


var t17 = db.Updateable<Student>().UpdateColumns(it => 
       new Student(){
        SchoolId = SqlFunc.Subqueryable<School>().Where(s => s.Id == it.SchoolId).Select(s => s.Id),
        Name = "newname"
       }).Where(it => it.Id == 1).ExecuteCommand();
UPDATE [STudent]  SET
            [SchoolId] = (SELECT TOP 1 [Id] FROM [School] WHERE ( [Id] =[STudent].[SchoolId] )) , 
            [Name] = @Const0   WHERE ( [ID] = @Id1 )


只更新Name並且 Name的值等於Name+1

//寫法1
var t8 = db.Updateable<Student>().UpdateColumns(it => new Student() { Name = it.Name+1}).Where(it => it.Id == 11).ExecuteCommand();
 
//寫法2 (注意:4.5.9.8以上版本支持) 如果只有一列可以簡化成這種寫法 
var t8= db.Updateable<Student>().UpdateColumns(it => it.Name == it.Name+1).Where(it => it.Id == 11).ExecuteCommand();




技巧功能

//根據不同條件執行更新不同的列
var t3 = db.Updateable(updateObj)
                .UpdateColumnsIF(caseValue=="1",it => new { it.Name })
                .UpdateColumnsIF(caseValue=="2", it => new { it.Name,it.CreateTime })
                .ExecuteCommand();


更新對數據的 版本控制


例如我想驗證我表單傳過來的數據在數據庫是否是最新的版本,不是最新版本拋出提示,

參考這個DEMO



https://github.com/sunkaixuan/SqlSugar/blob/dev/Src/Asp.Net/SqlServerTest/Demos/F_VersionValidation.cs
View Code

 

自己的演練,主要還是要參考:http://www.codeisbug.com/Doc/8/1121

太多了,不演練了,基本會用就好。

@天才卧龍的博客

執行SQL

Sqlqueryable

sqlueryable只支持查詢操作,並且支持拉姆達分頁

 

var t12 = db.SqlQueryable<Student>("select * from student").Where(it=>it.id>0).ToPageList(1, 2);

 

var t12 = db.SqlQueryable<dynamic>("select * from student").ToPageList(1, 2);//返回動態類型

 

 

Ado方法

1.重載:object parameters

var  dt=db.Ado.SqlQuery<Student>( "select * from table where id=@id and name=@name" , new  {id=1,name= "a" });
var  dt=db.Ado.SqlQuery<Student>( "select * from table where id=@id and name=@name" ,字典);

2.重載 List<SugarParameter> parameters

var  dt=db.Ado.GetDataTable( "select * from table where id=@id and name=@name" , new  List<SugarParameter>(){
   new  SugarParameter( "@id" ,1),
   new  SugarParameter( "@name" ,2)
});

3.重載params SugarParameter[] parameters

var  dt=db.Ado.GetDataTable( "select * from table" );
 
var  dt=db.Ado.GetDataTable( "select * from table where id=@id" , new  SugarParameter( "@id" ,1));
 
var  dt=db.Ado.GetDataTable( "select * from table where id=@id and name=@name" , new  SugarParameter []{
   new  SugarParameter( "@id" ,1),
   new  SugarParameter( "@name" ,2)
});

 

全部函數

 

1.獲取DataTable (如是.Net Core版本, DataTable是Sqlsugar自定義的DataTable, 因為以前的Core 1.x不支持DataTable, 后遺症, 效率不用擔心)

db.Ado.GetDataTable( string  sql,  object  parameters);
db.Ado.GetDataTable( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetDataTable( string  sql, List<SugarParameter> parameters);

 

2.獲取DataSet

db.Ado.GetDataSetAll( string  sql,  object  parameters);
db.Ado.GetDataSetAll( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetDataSetAll( string  sql, List<SugarParameter> parameters);

 

3.獲取DataReader

db.Ado.GetDataReader( string  sql,  object  parameters);
db.Ado.GetDataReader( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetDataReader( string  sql, List<SugarParameter> parameters);

 

4.獲取首行首列返回object類型

db.Ado.GetScalar( string  sql,  object  parameters);
db.Ado.GetScalar( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetScalar( string  sql, List<SugarParameter> parameters);

 

5.執行數據庫返回受影響行數

int  ExecuteCommand( string  sql,  object  parameters);
int  ExecuteCommand( string  sql,  params  SugarParameter[] parameters);
int  ExecuteCommand( string  sql, List<SugarParameter> parameters);

 

6.獲取首行首列更多重載

//以下為返回string
string  GetString( string  sql,  object  parameters);
string  GetString( string  sql,  params  SugarParameter[] parameters);
string  GetString( string  sql, List<SugarParameter> parameters);
 
//返回int
int  GetInt( string  sql,  object  pars);
int  GetInt( string  sql,  params  SugarParameter[] parameters);
int  GetInt( string  sql, List<SugarParameter> parameters);
 
//返回double
db.Ado.GetDouble( string  sql,  object  parameters);
db.Ado.GetDouble( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetDouble( string  sql, List<SugarParameter> parameters);
 
//返回decimal
db.Ado.GetDecimal( string  sql,  object  parameters);
db.Ado.GetDecimal( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetDecimal( string  sql, List<SugarParameter> parameters);
 
//返回DateTime
db.Ado.GetDateTime( string  sql,  object  parameters);
db.Ado.GetDateTime( string  sql,  params  SugarParameter[] parameters);
db.Ado.GetDateTime( string  sql, List<SugarParameter> parameters);

 

7.查詢並返回List<T>

db.Ado.SqlQuery<T>( string  sql,  object  whereObj =  null );
db.Ado.SqlQuery<T>( string  sql,  params  SugarParameter[] parameters);
db.Ado.SqlQuery<T>( string  sql, List<SugarParameter> parameters);

 

8.查詢返回單條記錄

db.Ado.SqlQuerySingle<T>( string  sql,  object  whereObj =  null );
db.Ado.SqlQuerySingle<T>( string  sql,  params  SugarParameter[] parameters);
db.Ado.SqlQuerySingle<T>( string  sql, List<SugarParameter> parameters);

 

9.查詢返回動態類型(該類型為Newtonsoft.Json里面的JObject類型, 使用方法自行百度)

db.Ado.SqlQueryDynamic( string  sql,  object  whereObj =  null );
db.Ado.SqlQueryDynamic( string  sql,  params  SugarParameter[] parameters);
db.Ado.SqlQueryDynamic( string  sql, List<SugarParameter> parameters);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM