Wpf 使用 Prism 实战开发Day11

仓储(Repository)/工作单元(Unit Of Work)模式

  •  仓储(rep):仓储接口定义了对实体类访问数据库及操作的方法。它统一管理数据访问的逻辑,并与业务逻辑层进行解耦。 简单的理解就是对访问数据库的一层接口封装。
  • 工作单元(uow):用来保证我们处理业务逻辑的,稳定性,完整性。防止在业务操作过程中,涉及对数据库多张表进行了增删改查(CURD)的时候,部分成功,部分失败。类似数据库中开的事务。

一.实现基础的仓储接口

1.新建一个 Repository (仓储) 文件夹,用来存放我们定义各个实体类对数据库操作的仓储。也就是对各个实体(表)进行增删改查的定义及实现,以及更高级的操作,例,分页,工作单元,事务,等等。

     1. 创建  待办事项仓储接口类 IToDoRepository  并且定义了(ToDo)实体对数据库CURD 的方法 

    public interface IToDoRepository
    {
        Task Add(ToDo toDo);
        bool Delete(ToDo toDo);
        bool Update(ToDo toDo);
        Task GetToDo();
    }

      2. 创建待办事项仓储的 实现类 ToDoRepository。该类继承自 IToDoRepository 仓储接口,并且需要实现父类所有定义的方法。

public class ToDoRepository : IToDoRepository
{
    private readonly MyToDoContext doContext;

    public ToDoRepository(MyToDoContext doContext)
    {
        this.doContext = doContext;
    }
    /// 
    /// 增加
    /// 
    /// 
    /// 
    public async Task Add(ToDo toDo)
    {
         await doContext.ToDo.AddAsync(toDo);
        return await doContext.SaveChangesAsync()>0;
    }

    /// 
    /// 删除
    /// 
    /// 
    /// 
    public  bool Delete(ToDo toDo)
    {
        doContext.ToDo.Remove(toDo);    
        return  doContext.SaveChanges()>0;
    }

    /// 
    ///  更新
    /// 
    /// 
    /// 
    public bool Update(ToDo toDo)
    {
        doContext.ToDo.Update(new ToDo
        {
            Id = toDo.Id,
            Title=toDo.Title,
            Content=toDo.Content,
        });
        return  doContext.SaveChanges()>0;
    }
    /// 
    /// 查询
    /// 
    /// 
    public async Task GetToDo()
    {
       var toDo=await doContext.ToDo.FirstOrDefaultAsync();
        return toDo;
    }
}
  1.  以上就是定义和实现的某个实体类仓储的基础写法。并且接口命名规范要用大写字母 I开头,实现类就去掉 I 字母。例如:定义仓储接口类: IToDoRepository, 仓储接口实现类:ToDoRepository
  2. 执行完操作后,要保存到数据库,需要调用 SaveChangesAsync。异步方法需要加Async,同步方法则去掉Async.其他的方法使用异步或同步也是同样的道理。

 二.如何使用仓储

    1. 在 Program.cs 中,进行注入

builder.Services.AddScoped();

Wpf 使用 Prism 实战开发Day11_第1张图片

     2. 在控制器构造函数中实例化定义的仓储接口,并且通过 toDoRepository 实例去调用到定义的方法。

namespace MyToDo.Api.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly IToDoRepository toDoRepository;

        public WeatherForecastController(IToDoRepository toDoRepository)
        {
            this.toDoRepository = toDoRepository;
        }

        [HttpGet(Name = "GetToDo")]
        public async Task Get()
        {
           var  retsult= await toDoRepository.GetToDo();
            return retsult;
        }
        [HttpPost(Name = "Add")]
        public async Task AddAsync(ToDo toDo)
        {
            var retsult = await toDoRepository.Add(toDo);
            return retsult;
        }
        [HttpDelete(Name = "Delete")]
        public bool Deletes(ToDo toDo)
        {
            var retsult =  toDoRepository.Delete(toDo);
            return retsult;
        }
        [HttpPost(Name = "Update")]
        public bool UpdateAsync(ToDo toDo)
        {
            var retsult = toDoRepository.Update(toDo);
            return retsult;
        }
    }
}

Wpf 使用 Prism 实战开发Day11_第2张图片

  1. 测试接口的时候,点击Try in out,再执行 Execute.如果没有问题,就能看到查询返回的数据了。
  2. 注意:控制器里面的添加的路由,已经改成完整的路由了。由控制器/方法组合而成的唯一路由。例如:  [Route("[controller]/[action]")]
  3. 以上实现了 ToDo 实体对数据库基础的增删改查,虽然实际应用中还远远达不到使用需求,这个只是为了能去理解仓储模式的建立和使用。所有仓储底层操作数据库都大同小异。如果有别人写好的仓储,各性能各方面都相当ok,或者有其他的更主流的 orm框架,我们拿来用即可。避免重复造轮子,除非能造出更好的轮子了。

Wpf 使用 Prism 实战开发Day11_第3张图片


三.工作单元 (Unit Of Work)

  • 自个实现的仓储太简单,在实际应用中,如果涉及多张表操作,暂时无法保证数据的一致性。可能还需要花很多时间去修改代码达到使用需求。所以在 github 中已经有更好的实现方案 UnitOfWork,也包含了仓储接口的定义,直接拿来用即可。
  • 使用 uow 好处,多个仓储之间可以共享上下文(DbContext)以及保证操作数据一致性和完整性。

 1.  下载 Unit Of Work 源码

Wpf 使用 Prism 实战开发Day11_第4张图片

 2.在MyToDo.Api 项目中,创建一个 UnitOfWork 文件夹,并且把以下代码复制过来

Wpf 使用 Prism 实战开发Day11_第5张图片

 3. 创建一个类库项目去存放,共用的代码

Wpf 使用 Prism 实战开发Day11_第6张图片

4.选择 类库项目,点下一步,并且项目名称定义成 :MyToDo.Shared

Wpf 使用 Prism 实战开发Day11_第7张图片

5.把共用的代码,复制到 MyToDo.Shared 里面去

Wpf 使用 Prism 实战开发Day11_第8张图片

6.在MyToDo.Api 项目中,右键=》添加=》项目引用

Wpf 使用 Prism 实战开发Day11_第9张图片

7.勾选 MyToDo.Shared。表示在 MyToDo.Api引用该项目,点击确定。

Wpf 使用 Prism 实战开发Day11_第10张图片

8.最后,还需要在MyToDo.Api 项目的NuGet 中下载安装这个包

Microsoft.EntityFrameworkCore.AutoHistory 

Wpf 使用 Prism 实战开发Day11_第11张图片

  • 复制过来的代码,命名空间要更改。如果有其他报错,例如:报某个方法访问性不一至,找到那个方法。把访问修饰符 internal 改成public 就可以了。
  •  UnitOfWork 文件夹的源码以及 MyToDo.Shared 等2个公共文件夹里面的源码,自行去github下载了

  • 目前,整个完整的项目结构,如下:

Wpf 使用 Prism 实战开发Day11_第12张图片


四.如何使用工作单元 (Unit Of Work)

1. 先添加不同仓储的实现,例如,待办事项仓储 (ToDoRepository) 

    public class ToDoRepository : Repository, IRepository
    {
        public ToDoRepository(MyToDoContext dbContext) : base(dbContext)
        {

        }
    }

这个就是使用别人提供的 Unit Of Work中已写好的仓储接口,然后自己自定义仓储去继承并实现它的一个标准写法。这样就能调用到别人集成好的方法。集成到自己的业务逻辑中去。

Wpf 使用 Prism 实战开发Day11_第13张图片


2.在Program.cs 中进行依赖注入

builder.Services.AddDbContext(option =>
{
    //获取数据库连接
    var connectionString = builder.Configuration.GetConnectionString("ToDoConnection");
    //使用sqlite
    option.UseSqlite(connectionString);
}).AddUnitOfWork() //注入工作单元
.AddCustomRepository() //注入仓储
.AddCustomRepository()
.AddCustomRepository();

Wpf 使用 Prism 实战开发Day11_第14张图片


 3.使用方式

namespace MyToDo.Api.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly IUnitOfWork unitOfWork;

        public WeatherForecastController(IUnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }

        [HttpGet(Name = "GetToDo")]
        public async Task> Get()
        {
            var  service= unitOfWork.GetRepository();//获取仓储服务
            return (List)await service.GetAllAsync();
            
        }
    }
}

4.最后效果

Wpf 使用 Prism 实战开发Day11_第15张图片

你可能感兴趣的:(WPF入门,数据库,c#)