Dapper.Common基於Dapper的開源LINQ超輕量擴展


Dapper.Common

  Dapper.Common是基於Dapper的LINQ實現,支持.net core,遵循Linq語法規則、鏈式調用、配置簡單、上手快,支持Mysql,Sqlserver(目前只實現了這兩個數據庫,實現其他數據庫也很輕松),支持單表,多表,自定義函數等功能。源碼及其簡單,直白,解析Lambda只有300行左右代碼。嚴格區分C#函數和數據庫函數,你可以在表達式中調用C#函數(不推薦,推薦將計算結果保存到變量,在寫入lambda表達式),性能損失在表達式編譯:常量>變量>函數。損失多少可以通過ExpressionUtil.BuildExpression()來測試,幾萬次耗時百毫秒及別。

  開源地址:https://github.com/1448376744/Dapper.Common

  Nuget:Install-Package Dapper.Common -Version 1.5.0

0.Test

 

1.Mapper

  public class User
  {
       /// <summary>
/// 如果表名與字段名一致,可以不用Column進行注解,主鍵采用類型的第一個屬性【不推薦】
/// name:用於映射字段名和數據庫字段不一致【完全可以用T4一鍵生成我GitHub有現成的】 /// key: /// 目前實現了Primary的定義,設置為Primary的字段update實體時,默認采用該字段為更新條件 /// isIdentity: /// 設置未true時在Insert時不會向該字段設置任何值 /// isColumn: /// 標識該字段是否在數據庫存在,用於擴展User而不在sql中生成該字段 /// </summary> [Column(name: "id", key: ColumnKey.Primary, isIdentity: true, isColumn: true)] public int? Id { get; set; } [Column(name:"nick_name")] public string NickName { get; set; } [Column(name: "create_time")] public DateTime? CreateTime { get; set; } }

2.Config

//在App啟動時執行一次即可
SessionFactory.AddDataSource(new DataSource()
{
    Name = "mysql",
    Source = () => new SqlConnection("connectionString"),
    SourceType = DataSourceType.SQLSERVER,
    UseProxy = true//使用Session的靜態代理實現,記錄日志,執行耗時,線上環境建議關閉代理
});
//獲取數據庫上下文 using (var session = SessionFactory.GetSession("msql")) { //linq to sql }

3.Insert

var entity = new User()
{
    CreateTime=DateTime.Now,
    NickName="dapper",
};
//絕大部分接口可以設置condition已決定是否執行,支持批量更新
session.From<User>().Insert(entity,condition:1>2);
//查看日志,如果出現異常,應該在catch里,查看session.Loggers
var loggers = session.Loggers;

2.Update

var entity = new User()
{
  Id=2,
  NickName="李四"
};
//更新所有字段(where id=2),支持批量,顯然除NickName之外將被更新成null session.From<User>().Update(entity); //更新部分字段 session.From<User>() .Set(a => a.NickName, "李四", condition: true)//condition為true時更新該字段 .Set(a => a.Balance, a => a.Balance + 100)//余額在原來基礎增加100 .Where(a => a.Id.In(1,2,3))//將id為1,2,3的記錄進行更新 .Update();

3.Delete

//刪除id>5||nick_name like '%da%'
 session.From<User>()
    .Where(a=>a.Id>5||a.NickName.Like("da"))
    .Delete();

4.Single

  //查詢全部字段
  var user1 = session.From<User>()
      .Where(a=>a.Id==2)
      .Single();
 
  //查詢部分字段
  var user2 = session.From<User>()
     .Where(a => a.Id == 2)
     .Single(s=>new
     {
         s.Id,
         s.NickName
     });

5.Select

 //查詢:where id in(1,2,3)
 var list = session.From<User>()
        .Where(a => a.Id.In("1,2,3".Split(',')))
        .Select();

6.Where

 //構建動態查詢,condition: true執行,通過condition選擇分支,多個where之間用 and 連接
 var list = session.From<User>()
        .Where(a => a.Id.In(1, 2, 3), condition: true)
        .Where(a => a.NickName.Like("da"), condition: false)
        .Where(a => a.Id > 2 || (a.NickName.Like("da") && a.Balance > 50))
        .Where("select * from user_bill where user_bill.user_id=user.id")//同樣可以當作字符串拼接工具
        .Select();

7.Function

 /// <summary>
 /// 自定義函數
 /// </summary>
 public static class MySqlFun
 {
     //這里使用泛型並不是必須的,只用函數名在數據庫存在即可,泛型為了指定返回數據類型
     [Function]//Dapper.Common嚴格區分C#函數和數據庫函數,一定要用該特性標識數據庫函數
     public static T COUNT<T>(T column)
     {
         return default(T);
     }
     [Function]
     public static T MAX<T>(T column)
     {
         return default(T);
     }
     [Function]
     public static T DISTINCT<T>(T column)
     {
         return default(T);
     }
   [Function]
   public static T DATE<T>(T column)
{
     return default(T);
   }
}

8.GroupBy

 var list = session.From<Order>()
     .GroupBy(a => a.UserId)//多個條件可以new一個匿名對象,也可以並聯多個group
     .Having(a => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > 10)//count(distinct(user_id))>10
     .Select(s => new
     {
         s.UserId,
         OrderCount = MySqlFun.COUNT(1L),//這里應該返回long int,
         MaxFee = MySqlFun.MAX(s.TotalFee)
     });

9.Join

 var list = session.From<Order, User>()
     .Join((a, b) => a.UserId == b.Id, JoinType.Inner)
     .GroupBy((a, b) => a.UserId)
     .Having((a, b) => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > 10)//count(distinct(user_id))>10
     .Select((a, b) => new
     {
         a.UserId,
         b.NickName,
         OrderCount = MySqlFun.COUNT(1L),//這里應該返回long int,
         MaxFee = MySqlFun.MAX(a.TotalFee)
     });

10.SubQuery

var list = session.From<Order>()
    .GroupBy(a  => a.UserId)
    .Having(a => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > 10)
    .Select(a => new
    {
        a.UserId,
        UserName=Convert.ToString("select nick_name from user where user.id=order.user_id"),//如果這個子查詢返回的是int:Convert.ToInt32(sql)
        OrderCount = MySqlFun.COUNT(1L),//這里應該返回long int【這就是為什么定義成泛型函數】,
        MaxFee = MySqlFun.MAX(a.TotalFee)
    });

11.Page

//分頁應該寫在Where,Having,Group之后(如果有)
var
list = session.From<User>() .Where(a=>a.NickName != null) .Page(1,10,out long total) .Select();

12.Take

var list = session.From<User>()
        .Take(5)
        .Select();

13.Skip

//從數據庫索引為1的位置(跳過1之前的記錄),獲取10
var
list = session.From<User>() .Skip(1,10) .Select();

14.Sum

var list= session.From<User>()
     .Sum(s=>s.Balance*s.Id);

15.Exists

//內部采用exist子查詢判斷滿足where條件的記錄是否存在
var
flag = seesion.From<User>() .Where(a=>a.Id > 10) .Exists();

16.OrderBy

var list1 = session.From<User>()
    .Order(a=>a.Id)
    .Select();

var list2 = session.From<User>()
    .GroupBy(a => MysqlFun.DATE(a.CreateTime))
    .OrderByDescending(a => MysqlFun.DATE(a.CreateTime))
    .Select(s=>new 
    {
         Date=MysqlFun.DATE(s.CreateTime),
         Count = MysqlFun.Count(1L)
    });

17.Filter

var user =new User ()
{
  Id = 12   Balance
= 50,   NickName = "張三",   CreateTime = Datetime.Now }; //Filter會在Insert,Update,Select,過濾掉不想要的字段
//這將不會更新余額及創建時間
var row = session.From<User>() .Filter(f=>new { f.CreateTime, f.Balance, }) .Update(user);

 18.Transaction

  //獲取數據庫上下文
  ISession session = null;
  try
  {
    session=SessionFactory.GetSession();
//開啟事務 session.Open(true); //sql //提交事務 session.Commit(); } catch (Exception) { session?.Rollback(); throw; } finally { session?.Close(); }

 19.Custom Page

//該策略可適用於百萬級別,單表條件查詢
//思想:先只查滿足條件的id,並分頁,然后where in (idArray)查詳情
//還有一種超高性能的分頁思想:每一頁更具上一頁最大id開始向下分頁查詢,同樣可以集成到這一個方法里(加個分頁類型參數)
public static Dapper.Extension.IQueryable<T> SPage<T>(this Dapper.Extension.IQueryable<T> queryable, int index, int count, out long total) where T : class, new() { total = 0; if (index <= 90000) { //采用limit queryable.Page(index, count, out total); } //對mysql進行擴展 else if (queryable is MysqlQuery<T> mysqlQuery) { total = queryable.Count(); var table = EntityUtil.GetTable<T>(); var idName = table.Columns.Find(f => f.ColumnKey == ColumnKey.Primary).ColumnName; //先只查詢主鍵字段並分頁 var where = mysqlQuery._whereBuffer.Length > 0 ? "where " + mysqlQuery._whereBuffer : ""; var orderby = mysqlQuery._orderBuffer.Length > 0 ? "order by" + mysqlQuery._orderBuffer : ""; var sql = string.Format("select {0} from {1} {2} {3} limit {4},{5}", idName, table.TableName, where, orderby, (index - 1) * count, count); var idArray = mysqlQuery._session.Query<long>(sql, mysqlQuery._param); //重置 mysqlQuery._whereBuffer.Clear(); //新建條件 if (idArray.Count() > 0) { queryable.Where(string.Format("{0} in @idArray", idName), p => p.Add("@idArray", idArray)); } } return queryable; } var row = Session.From<Member>() .SPage(2,2,out long total) .Select();

 


免責聲明!

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



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