C#.NET ORM 如何访问 Access 数据库 [FreeSql]( 二 )

定义 DB.cs 类之后就可以快乐的 CRUD 了 。FreeSql 提供多种 CRUD 使用习惯,请根据实际情况选择团队合适的一种:

  • 要么 FreeSql,原始用法;
  • 要么 FreeSql.Repository,仓储 + 工作单元习惯;
  • 要么 FreeSql.DbContext,很像 EFCore 的使用习惯,兼容 EFCore 99% 的实体注解;
  • 要么 FreeSql.BaseEntity,充血模式;
  • 要么 直接像 dapper 那样使用 SqlConnection 扩展方法;
CRUD 模式一:原始用法 APIDB.access.Select<T>(); //查询DB.access.Insert<T>(); //插入DB.access.Update<T>(); //更新DB.access.Delete<T>(); //删除DB.access.InsertOrUpdate<T>()// 插入或更新DB.access.Transaction(..); //事务DB.access.CodeFirst; //CodeFirst 对象DB.access.DbFirst; //DbFirst 对象DB.access.Ado; //Ado 对象DB.access.Aop; //Aop 对象DB.access.GlobalFilter; //全局过滤器对象var blogs = DB.access.Select<Blog>().Where(b => b.Rating > 3).OrderBy(b => b.Url).Page(2, 10).ToList();var blog = new Blog { Url = "http://sample.com" };blog.BlogId = (int)DB.access.Insert(blog).ExecuteIdentity();DB.access.Update<Blog>().Set(b => b.Url, "http://sample2222.com").Where(b => b.Url == "http://sample.com").ExecuteAffrows();DB.access.Delete<Blog>().Where(b => b.Url == "http://sample.com").ExecuteAffrows();// 等等等 。。级联保存、级联查询、导航属性 。。。CRUD 模式二:仓储 + 工作单元FreeSql.Repository 作为扩展,实现了通用仓储层功能 。与其他规范标准一样,仓储层也有相应的规范定义 。FreeSql.Repository 参考 abp vnext 接口,定义和实现基础的仓储层(CURD),算比较通用的方法 。
  • Select/Attach 快照对象,Update 只更新变化的字段;
  • Insert 插入数据,适配各数据库优化执行 ExecuteAffrows/ExecuteIdentity/ExecuteInserted;
  • InsertOrUpdate 插入或更新;
  • SaveMany 方法快速保存导航对象(一对多、多对多);
  • 工作单元管理事务
//Startup.cspublic void ConfigureServices(IServiceCollection services){services.AddSingleton<IFreeSql>(DB.access);services.AddScoped<UnitOfWorkManager>();services.AddFreeRepository(null, typeof(Startup).Assembly);//批量注入 Service}public class SongService{readonly IBaseRepository<Song> _repoSong;readonly IBaseRepository<Detail> _repoDetail;public SongService(IBaseRepository<Song> repoSong, IBaseRepository<Detail> repoDetail){_repoSong = repoSong;_repoDetail = repoDetail;}[Transactional]public virtual void Test1(){//这里 _repoSong、_repoDetail 所有操作都是一个工作单元this.Test2();}[Transactional(Propagation = Propagation.Nested)]public virtual void Test2() //嵌套事务{//这里 _repoSong、_repoDetail 所有操作都是一个工作单元}}属性返回值说明EntityTypeType仓储正在操作的实体类型,注意它不一定是 TEntityUnitOfWorkIUnitOfWork正在使用的工作单元OrmIFreeSql正在使用的 OrmDbContextOptionsDbContextOptions正在使用的 DbContext 设置,修改设置不影响其他DataFilterIDataFilter<TEntity>仓储过滤器,本对象内生效UpdateDiyIUpdate<TEntity>准备更新数据,与仓储同事务SelectISelect<TEntity>准备查询数据方法返回值参数说明AsTypevoidType改变仓储正在操作的实体类型GetTEntityTKey根据主键,查询数据FindTEntityTKey根据主键,查询数据DeleteintTKey根据主键删除数据DeleteintLambda根据 lambda 条件删除数据DeleteintTEntity删除数据DeleteintIEnumerable<TEntity>批量删除数据DeleteCascadeByDatabaseList<object>Lambda根据导航属性递归数据库删除数据Insert-TEntity插入数据,若实体有自增列,插入后的自增值会填充到实体中Insert-IEnumerable<TEntity>批量插入数据Update-TEntity更新数据Update-IEnumerable<TEntity>批量更新数据InsertOrUpdate-TEntity插入或更新数据FlushState-无清除状态管理数据Attach-TEntity附加实体到状态管理,可用于不查询就更新或删除Attach-IEnumerable<TEntity>批量附加实体到状态管理AttachOnlyPrimary-TEntity只附加实体的主键数据到状态管理SaveMany-TEntity, string保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比)BeginEdit-List<TEntity>准备编辑一个 List 实体EndEditint无完成编辑数据,进行保存动作

经验总结扩展阅读