藉助表達式樹感受不一樣的CRUD Intro 最近有個想法,想不寫 sql 語句,做一個類似於 ORM 的東西,自己解析表達式樹,生成要執行的 sql 語句,最後再執行 sql 語句,返回相應結果。 思路解析 常用的 sql 語句基本都有一定的模式,就是 /`DELETE Update SELECT ...
藉助表達式樹感受不一樣的CRUD
Intro
最近有個想法,想不寫 sql 語句,做一個類似於 ORM 的東西,自己解析表達式樹,生成要執行的 sql 語句,最後再執行 sql 語句,返回相應結果。
思路解析
常用的 sql 語句基本都有一定的模式,就是 INSERT
/DELETE
/Update
/SELECT
,我把公用的部分給抽離出來,把查詢/更新/刪除條件和指定欄位通過表達式樹來指出,解析傳入的表達式樹對象來獲取條件以及要更新的欄位。
源碼
源碼鏈接
Sample
請看使用示例:
安裝 nuget 包 WihanLi.Common
public static class RepositoryTest
{
public static void MainTest()
{
var connectionPool = new DbConnectionPool(new DbConnectionPoolPolicy(ConfigurationHelper.ConnectionString("TestDb")));
var repo = new Repository<TestEntity>(() => connectionPool.Get());
repo.Insert(new TestEntity
{
Token = "1233",
CreatedTime = DateTime.UtcNow
});
var entity = repo.Fetch(t => t.PKID == 1);
System.Console.WriteLine(entity.Token);
repo.Update(t => t.PKID == 1, t => t.Token, 1);
entity = repo.Fetch(t => t.PKID == 1);
System.Console.WriteLine(entity.Token);
repo.Delete(t => t.PKID == 1);
entity = repo.Fetch(t => t.PKID == 1);
System.Console.WriteLine($"delete operation {(entity == null ? "Success" : "Failed")}");
repo.Execute("TRUNCATE TABLE dbo.tabTestEntity");
Console.WriteLine("finished.");
}
public class DbConnectionPool : DefaultObjectPool<DbConnection>
{
public DbConnectionPool(IPooledObjectPolicy<DbConnection> policy) : base(policy)
{
}
public DbConnectionPool(IPooledObjectPolicy<DbConnection> policy, int maximumRetained) : base(policy, maximumRetained)
{
}
}
public class DbConnectionPoolPolicy : IPooledObjectPolicy<DbConnection>
{
private readonly string _connString;
public DbConnectionPoolPolicy(string connString)
{
_connString = connString;
}
public DbConnection Create()
{
return new SqlConnection(_connString);
}
public bool Return(DbConnection obj)
{
return obj.ConnectionString.IsNotNullOrWhiteSpace();
}
}
[Table("tabTestEntity")]
internal class TestEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PKID { get; set; }
public string Token { get; set; }
public DateTime CreatedTime { get; set; }
}
}
示例使用了 ObjectPool 實現了一個資料庫連接池,Repository
實例化需要一個獲取 DbConnection 對象的委托,而資料庫連接就是從這資料庫連接池中獲取。
不足/TODO
- 支持通過 Column 自定義列名稱
- 支持指數化查詢,現在是將條件直接拼接成了字元串,做了防註入處理,要改成使用參數化查詢
- 支持更多的方法解析成對應的 Sql 語句