net下的高性能輕量化半自動orm+linq的《SqlBatis》


一、項目介紹

該項目內置單表linq操作,xml動態sql解析,詞法分析,類型映射等功能。

  1. SqlMapper,用來處理sql與數據庫操作,它設計的目標是支持mysql,sqlserver,sqllite,pgsql等.

  2. TypeMapper用於完成將數據庫的字段類型映射到C#類型,內部定義了類型轉換函數和轉換規則.

  3. TypeConvert用於完成數據庫記錄到C#類型的轉換。通過IL動態創建IDataReader對象到C#實體類的轉換函數和將C#對象解構成Key-value的函數.

  4. ExpressionContext是一個輕量的詞法分析器,用於將字符串表達式生成C#表達式,進而生成委托.

  5. XmlResovle用於解析xml配置,如果你的項目僅需要xml動態解析功能你完全可以下載我的源碼進行改進(它在github中開源),半自動意味着超高的性能
  6. https://github.com/1448376744/SqlBatis

二 、詞法分析器

該類型的實例是線程安全的,可復用的。它的設計及其簡單,功能也很有限,但是對於我們的需求足夠了. 它的實現邏輯如下:

var expr = "(Age!=null) && (Name=='zs')";
/**

1.通過正則匹配出每一個括號,因此你必須手動的給每個二元表達式加括號,它無法識別運算符的優先級.
$1 = (Age!=null)
$2 = (Name=='zs')
$3 = $1 && $2

2.創建參數類型
Expression.Parameter(typeof(T), "p");

3.逐個創建二元表達式
Expression.MakeUnary(ExpressionType.Convert, expr, type)
...
*/
var context = new ExpressionContext();
//Age必須是可以為null的類型:int?
var result = context.Create<Student>("(Age != null) && (Name=='zs')");
var flag= result.Func(new Student { Age =(int?) 1, Name = "zs" });
/**
常見錯誤:
1. (Age != null) && Name=='zs'
缺少括號 2. public class Student{ public int Age{get;set;} public string Name {get;set;}}
Age必須是int?類型 */

  

ExpressionContext

var context = new ExpressionContext();
var result = context.Create<Student>("(Age!=null)&&(Name=='zs')");
var expr = result.LambdaExpression;
Func<Student, bool> func = result.Func;
var flag = func(new Student { Age = 1, Name = "zs" });

  

三、XML解析

<?xml version="1.0" encoding="utf-8" ?>

<commands namespace="sutdent">

  <!--
    框架只定義了if,variable,where等標簽
    insert,select可以隨意,並沒有實際意義
  -->
  <variable id="columns">
    Id,Age,Name
  </variable>

  <select id="list-dynamic">
    select ${columns} from student
    <where>
      <if test="Id!=null" value="id=@Id"/>
    </where>
    limit 0,1   
  </select>

  <insert id="add">
    insert into student(name,age)values(@Name,@age)
  </insert>

</commands>
 
//解析sql var resovle = new XmlResovle(); resovle.Load(@"E:\SqlBatis\SqlBatis.Test", "*.xml"); //普通sql var sql1 = resovle.Resolve("namespace.id"); //動態sql var sql2 = resovle.Resolve("namespace.id",new { Id=(int?)null,Age=2});

 四、配置DbContext

  方式1

public class MysqlDbConrext : DbContext
{
    public IDbQuery<Student> Students { get => new DbQuery<Student>(this); }
    private static readonly IXmlResovle resovle;
    static MysqlDbConrext()
    {
//不要為每一個DbContext加載配置 resovle = new XmlResovle(); resovle.Load(@"E:\SqlBatis\SqlBatis.Test","*.xml"); } protected override void OnLogging(string message, object parameter = null, int? commandTimeout = null, CommandType? commandType = null) { } protected override DbContextBuilder OnConfiguring(DbContextBuilder builder) { ILoggerFactory factory = LoggerFactory.Create(b => { b.AddConsole(); b.AddDebug(); b.SetMinimumLevel(LogLevel.Debug); }); builder.Connection = new MySql.Data.MySqlClient.MySqlConnection("server=127.0.0.1;user id=root;password=1024;database=test;"); builder.XmlResovle = null; return builder; } public MysqlDbConrext() { Students = new DbQuery<Student>(this); } }

 方式2

var db = new DbContext(new DbContextBuilder()
{ 
    DbContextType=DbContextType.Mysql,
    ...
});

五、XML+Linq

using (var db = new SqlDbContext())
{
    //linq
    var row = db.Students.Delete();
    var (list, count) = db.Students
        .Page(1, 2)
        .SelectMany();
    //dynamic
    var p = new { Id = (int?)null, Name = "zs" };
    var dylist = db.Students
       .Where(a => a.Id == 1, p.Id != null)
       .Where(a => a.Name == p.Name, p.Name != null)
       .SelectMany();
    //xml
    row = db.From("sutdent.add", new Student()
    {
        Age = 20,
        IsDelete = true,
        Name = "xml"
    }).ExecuteNonQuery();
    //dynamic:注意由於內部會緩存表達式創建的委托,因此同一個動態的xml命令不能用不同的參數去獲取它
    //建議如果獲取的xml命令是動態的,則應保證整個項目只有一次獲取的代碼,或者使用同一種參數類型
    row = db.From("stutdent.list-dynamic", p).ExecuteNonQuery();
    //多結果集查詢,xml方式同樣支持
    using (var muti = db.ExecuteMultiQuery("select * from student;select count(1) from student;"))
    {
        //第一個結果集
        var list = muti.GetList<Student>();
        //第二個結果集
        var count = muti.Get<int>();
    }
}

  

  

  

 


免責聲明!

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



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