It's nearly a year since FreeSql was released as an open source. At present, there are 64118 lines of code in the main warehouse. The commands counted by git command are as follows:
find . "(" -name "*.cs" ")" -print | xargs wc -l
Add in the code of several other expansion packages, there are about 70000 lines of source code.
Warehouse address: https://github.com/2881099/Fr...
On the day of the golden nine silver ten, two major support updates were released, namely. Netframework 4.0 and ODBC.
With the continuous iterative updating, it becomes more and more stable and powerful. It is expected to release the official version of 1.0 on the first anniversary (January 1, 2020).
Because of the space, it is too short to be on the homepage. At the same time, I'm sorry for the audience. Here are some more practical functions that have been updated recently:
ISelect.ToDelete/ToUpdate
CRUD methods of IFreeSql correspond to IInsert, ISelect, IUpdate and IDelete respectively.
By default, IDelete does not support navigation objects, multi table Association, etc. ISelect.ToDelete can turn query objects into delete objects to support navigation objects or other query functions to delete data, as follows:
fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows();
Note: this method is not to query the data to the memory loop for deletion. The above code generates the following SQL execution:
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)
Benefits of using this solution for complex deletion:
- Test data can be previewed before deletion to prevent incorrect deletion and realize the checked or deleted operation.
- Support more complex delete operations (IDelete only supports simple operations by default), and even use Limit(10) on ISelect to delete only the first 10 records with conditions attached;
The ToUpdate function is about the same.
GlobalFilter global filter
The FreeSql base layer implements the global filter function that can be set by 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");
The Apply generic parameter can be set to any type. When the Select/Update/Delete method is used, a filter matching attempt (try catch) will be made:
- If the match is successful, the where condition will be attached;
- If the match fails, the mark will not match again next time to avoid performance loss;
How to disable?
fsql.Select<TestAddEnum>().ToList(); //All entry into force fsql.Select<TestAddEnum>().DisableGlobalFilter("test1").ToList(); //Disable test1 fsql.Select<TestAddEnum>().DisableGlobalFilter().ToList(); //Disable all
The effect of fsql.Update/Delete method is the same as above.
Storage filter (old function)
This is a previously supported feature. FreeSql.Repository also implements the function of filter. It not only filters when querying, but also validates when deleting / modifying / inserting to avoid data security problems.
Note: the warehouse filter is not a function of IFreeSql.GlobalFilter, which can take effect at the same time
Each warehouse instance has the idataflilter attribute, which can be used to complete filter management. It is independent and does not affect the global after modification.
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); }
Temporary disable
using (repo1.DataFilter.Disable("test")) { //In this section, the test filter of repo1 fails } //repo1's test filter takes effect again
Filtering and validation
Suppose we have two entities, user and topic, and two warehouses are defined in the domain class:
var userRepository = fsql.GetGuidRepository<User>(); var topicRepository = fsql.GetGuidRepository<Topic>();
In the development process, we always worry about the data security of the topic repository, that is, it is possible to query or operate on other users' topics. So we improved it in v0.0.7 and added the filter lambda expression parameter.
var userRepository = fsql.GetGuidRepository<User>(a => a.Id == 1); var topicRepository = fsql.GetGuidRepository<Topic>(a => a.UserId == 1);
- This condition is attached when querying / modifying / deleting, so that the data of other users will not be modified.
- When adding, use expression to verify the validity of data, and throw an exception if it is not legal;
Entity change notice
This function is implemented on FreeSql.Repository, which can forward the changes of entities in a unified way, so as to realize the global or local log like function.
Global settings:
fsql.SetDbContextOptions(opt => { opt.OnEntityChange = report => { Console.WriteLine(report); }; });
Set DbContext or UnitOfWork separately:
var ctx = fsql.CreateDbContext(); ctx.Options.OnEntityChange = report => { Console.WriteLine(report); }; var uow = fsql.CreateUnitOfWork(); uow.OnEntityChange = report => { Console.WriteLine(report); };
The parameter report is a List collection. The type definition of collection elements is as follows:
public class EntityChangeInfo { public object Object { get; set; } public EntityChangeType Type { get; set; } } public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
Type of change- | Explain |
---|---|
Insert | Solid objects are inserted |
Update | Entity object is updated |
Delete | Entity object deleted |
SqlRaw | Executed SQL statement |
At present, SqlRaw has two special features:
- Delete all intermediate tables when updating navigation attributes at multi to multi join level;
- The general warehouse class BaseRepository has a Delete method, and the parameter is an expression, not an entity.
int Delete(Expression<Func<TEntity, bool>> predicate);
DbContext.SaveChanges, or Repository Insert/Update/Delete, or UnitOfWork.Commit will trigger the event at most once.
More functions
Please move to update the log: https://github.com/2881099/Fr...