FreeSql 開源發佈快一年了,目前主倉庫代碼量 64118 行,用 git 命令統計的命令以下:git
find . "(" -name "*.cs" ")" -print | xargs wc -lgithub
加上其餘幾個擴展包的代碼,大約有 70000 行源碼。sql
倉庫地址:https://github.com/2881099/FreeSql安全
在金九銀十的日子,發佈了兩大重要支持更新,分別是 .NetFramework4.0 和 ODBC。性能
隨着不斷的迭代更新,愈來愈穩定,也愈來愈強大。預計在一週年的時候(2020年1月1日)發佈 1.0 正式版本。測試
因爲篇幅緣由,過短則上不了首頁,同時也對不起觀衆,下面介紹一下最近更新的幾個較實用的功能:ui
IFreeSql 之 CRUD 方法,分別對應 IInsert、ISelect、IUpdate、IDelete。日誌
IDelete 默認不支持導航對象,多表關聯等。ISelect.ToDelete 可將查詢對象轉爲刪除對象,以便支持導航對象或其餘查詢功能刪除數據,以下:code
fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows();
注意:此方法不是將數據查詢到內存循環刪除,上面的代碼產生以下 SQL 執行:對象
DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1)
複雜刪除使用該方案的好處:
ToUpdate 功能大概相同。
FreeSql 基礎層實現了 Select/Update/Delete 可設置的全局過濾器功能。
public static AsyncLocal<Guid> TenantId { get; set; } = new AsyncLocal<Guid>(); fsql.GlobalFilter .Apply<TestAddEnum>("test1", a => a.Id == TenantId.Value) .Apply<AuthorTest>("test2", a => a.Id == 111) .Apply<AuthorTest>("test3", a => a.Name == "11");
Apply 泛型參數能夠設置爲任何類型,當使用 Select/Update/Delete 方法時會進行過濾器匹配嘗試(try catch):
如何禁用?
fsql.Select<TestAddEnum>().ToList(); //全部生效 fsql.Select<TestAddEnum>().DisableGlobalFilter("test1").ToList(); //禁用 test1 fsql.Select<TestAddEnum>().DisableGlobalFilter().ToList(); //禁用全部
fsql.Update/Delete 方法效果同上。
這是一個原先就支持了的功能。FreeSql.Repository 也一樣實現了過濾器功能,它不只是查詢時過濾,連刪除/修改/插入時都會進行驗證,避免數據安全問題。
注意:倉儲的過濾器與 IFreeSql.GlobalFilter 不是一個功能,能夠同時生效
每一個倉儲實例都有 IDataFilter 屬性,可利用其完成過濾器管理,它是獨立的修改後不影響全局。
public interface IDataFilter<TEntity> where TEntity : class { IDataFilter<TEntity> Apply(string filterName, Expression<Func<TEntity, bool>> filterAndValidateExp); IDisposable Enable(params string[] filterName); IDisposable EnableAll(); IDisposable Disable(params string[] filterName); IDisposable DisableAll(); bool IsEnabled(string filterName); }
using (repo1.DataFilter.Disable("test")) { //在這段中,repo1 之 test 過濾器失效 } //repo1 之 test 過濾器從新生效
假設咱們有User(用戶)、Topic(主題)兩個實體,在領域類中定義了兩個倉儲:
var userRepository = fsql.GetGuidRepository<User>(); var topicRepository = fsql.GetGuidRepository<Topic>();
在開發過程當中,老是擔憂 topicRepository 的數據安全問題,即有可能查詢或操做到其餘用戶的主題。所以咱們在v0.0.7版本進行了改進,增長了 filter lambda 表達式參數。
var userRepository = fsql.GetGuidRepository<User>(a => a.Id == 1); var topicRepository = fsql.GetGuidRepository<Topic>(a => a.UserId == 1);
該功能依附在 FreeSql.Repository 上實現的,對實體的變化進行統一轉發,以便實現全局或局部相似日誌的功能。
全局設置:
fsql.SetDbContextOptions(opt => { opt.OnEntityChange = report => { Console.WriteLine(report); }; });
單獨設置 DbContext 或者 UnitOfWork:
var ctx = fsql.CreateDbContext(); ctx.Options.OnEntityChange = report => { Console.WriteLine(report); }; var uow = fsql.CreateUnitOfWork(); uow.OnEntityChange = report => { Console.WriteLine(report); };
參數 report 是一個 List 集合,集合元素的類型定義以下:
public class EntityChangeInfo { public object Object { get; set; } public EntityChangeType Type { get; set; } } public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
變化類型- | 說明 |
---|---|
Insert | 實體對象被插入 |
Update | 實體對象被更新 |
Delete | 實體對象被刪除 |
SqlRaw | 執行了SQL語句 |
SqlRaw 目前有兩處地方比較特殊:
int Delete(Expression<Func<TEntity, bool>> predicate);
DbContext.SaveChanges,或者 Repository 對實體的 Insert/Update/Delete,或者 UnitOfWork.Commit 操做都會最多觸發一次該事件。
請移步更新日誌:https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97