简体   繁体   English

如何在我的 ASP.NET 核心 Web API 项目中使用工作单元模式和通用存储库模式?

[英]How can I use unit of work pattern with generic repository pattern in my ASP.NET Core Web API project?

There are many examples on the inte.net about the use of unit of work and generic repository together, but I couldn't find exactly how to apply the unit of work repository pattern to my own project. inte.net 上有很多关于一起使用工作单元和通用存储库的示例,但我找不到确切的如何将工作单元存储库模式应用到我自己的项目中。 Because everyone did it differently.因为每个人做的都不一样。

Actually, I set up the unit of work structure, but I don't quite understand how I can use it in my own project?实际上,我设置了工作单元结构,但我不太明白如何在我自己的项目中使用它? How can I apply the unit of work repository I made to my own project?如何将我创建的工作单元存储库应用到我自己的项目中? Can you help me with this?你能帮我吗? Can you tell me if I have a mistake?如果我有错误,你能告诉我吗? This is how I saw the unit of work repository on the inte.net and implemented it.这就是我在 inte.net 上看到工作单元存储库并实现它的方式。

First of all, if I just talk about my project, my project is an ASP.NET Core Web API project and basically a 3-layer structure:首先,如果我只说我的项目,我的项目是一个 ASP.NET Core Web API 项目,基本上是一个 3 层结构:

  1. API layer. API层。 I have controllers in the API layer.我在 API 层有控制器。
  2. Second is the business layer.其次是业务层。 The business layer only serves to communicate with the data access layer.业务层仅用于与数据访问层进行通信。
  3. The third layer is the data access layer, in this layer I do the database operations, such as adding, deleting, updating.第三层是数据访问层,在这一层我做数据库的操作,比如增删改查。

I'm doing these with the generic repository.我正在使用通用存储库执行这些操作。 As an example, I am sharing some of my code below.例如,我在下面分享我的一些代码。

I just shared category as an example, but I have more than one class like category.我只是以共享类别为例,但我有多个 class 喜欢的类别。

API layer - CategoriesController : API 层 - CategoriesController控制器:

[Route("api/[controller]")]
[ApiController]
public class categoriesController : ControllerBase
{
    private ICategoryService category_service;
    DatabaseContext c = new DatabaseContext();

    public categoriesController(ICategoryService category_service)
    {
        this.category_service = category_service;
    }
   
    [HttpGet("getall")]
    public async Task<IActionResult> Get()
    {
        return Ok(await category_service.TGetAll());
    }

    [HttpGet("getbyid/{id}")]
    public async Task<IActionResult> GetByIdCategory(int id)
    {
        var category = await category_service.TGetById(id);

        if (category != null)
        {
            return Ok(category);  // 200 ok
        }
        else
        {
            return NotFound(); //404 not found
        }
    }

    [HttpPost("add")]
    public async Task<IActionResult> Add(Category category)
    {
        var result =  category_service.TAdd(category);

        if (result != null)
        {
            return Ok(result);
        }

        return BadRequest(result);
    }
}

Business layer - CategoryManager :业务层CategoryManager

public class CategoryManager:ICategoryService
{
    ICategoryDal _categoryDal;
       
    public CategoryManager(ICategoryDal _cateogoryDal)
    {
        this._categoryDal = _cateogoryDal;
    }

    public async Task<List<Category>> TGetAll()
    {
        return await _categoryDal.GetListAll();
    }

    public async Task<Category> TGetById(int id)
    {
        return await _categoryDal.GetByID(id);
    }

    public async Task TAdd(Category entity)
    {
        await _categoryDal.Insert(entity);
    }

    public async Task TDelete(Category entity) 
    {
        await _categoryDal.Delete(entity);
    }

    public async Task TUpdate(Category entity)
    {
        await _categoryDal.Update(entity);
    }
}

Data Access layer - CategoryRepository :数据访问层 - CategoryRepository

public class CategoryRepository : GenericRepository<Category>, ICategoryDal
{
}

GenericRepository : GenericRepository

public class GenericRepository<T> : IGenericDal<T> where T : class
{
    protected DatabaseContext dbContext;

    public GenericRepository(DatabaseContext context)
    {
        dbContext = context;
    }

    public async Task Delete(T t)
    {
        dbContext.Remove(t);
        await dbContext.SaveChangesAsync();
    }
     
    public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression)
    {
        return dbContext.Set<T>()
                        .Where(expression)
                        .AsNoTracking();
    }

    public async Task<T> GetByID(int id)
    {
        return await dbContext.Set<T>().FindAsync(id);
    }

    public async Task<List<T>> GetListAll()
    {
        return await dbContext.Set<T>().ToListAsync();
    }

    public async Task<List<T>> GetListAll(Expression<Func<T, bool>> filter)
    {
        return await dbContext.Set<T>()
                              .Where(filter)
                              .ToListAsync();
    }

    public async Task Insert(T t)
    {
        await dbContext.AddAsync(t);
        await dbContext.SaveChangesAsync();
    }

    public async Task Update(T t)
    {
        var updatedEntity = dbContext.Entry(t);
        updatedEntity.State = EntityState.Modified;
        dbContext.SaveChanges();
    }
}

UnitOfWork : UnitOfWork

public class UnitOfWorkRepository : IUnitOfWork
{
    private readonly DatabaseContext _dbContext;
    private IDbContextTransaction _transaction;
    private bool _disposed;

    public UnitOfWorkRepository(DatabaseContext dbContext)
    {
        _dbContext = dbContext;
    }

    public bool BeginNewTransaction()
    {
        try
        {
            _transaction = _dbContext.Database.BeginTransaction();
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this._disposed)
        {
            if (disposing)
            {
                _dbContext.Dispose();
            }
        }

        this._disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public IGenericDal<T> GetRepository<T>() where T : class
    {
        return new GenericRepository<T>(_dbContext);
    }

    public bool RollBackTransaction()
    {
        try
        {
            _transaction.Rollback();
            _transaction = null;
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    public int SaveChanges()
    {
        var transaction = _transaction != null ? _transaction : _dbContext.Database.BeginTransaction();

        using (transaction)
        {
            try
            {
                // Context boş ise hata fırlatıyoruz
                if (_dbContext == null)
                {
                    throw new ArgumentException("Context is null");
                }

                // SaveChanges metodundan dönen int result ı yakalayarak geri dönüyoruz.
                int result = _dbContext.SaveChanges();

                // Sorun yok ise kuyruktaki tüm işlemleri commit ederek bitiriyoruz.
                transaction.Commit();
                return result;
            }
            catch (Exception ex)
            {
                // Hata ile karşılaşılır ise işlemler geri alınıyor 
                transaction.Rollback();
                throw new Exception("Error on SaveChanges ", ex);
            }
        }
    }
}

IUnitOfWork : IUnitOfWork

public interface IUnitOfWork : IDisposable
{
    bool BeginNewTransaction();
    bool RollBackTransaction();
    IGenericDal<T> GetRepository<T>() where T : class;
    int SaveChanges();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用于发布实体的 Asp.Net 核心存储库和工作单元模式 - Asp.Net core Repository and Unit Of Work Pattern for Posting an entity Asp.net核心通用存储库模式,继承不起作用 - Asp.net core generic repository pattern with inheritance not working Asp.Net Core 通用存储库模式软删除 - Asp.Net Core Generic Repository Pattern Soft Delete 在ASP.NET Core中以现有存储库模式正确实现工作单元 - Proper Implementation of Unit of Work in Existing Repository Pattern in ASP.NET Core 通用存储库模式 ASP NET CORE Web Api:使用包含异步 - Generic repository pattern ASP NET CORE Web Api: using include with async asp.net core C# 如何在存储库模式中传递值 - asp.net core C# how can I pass value in a repository pattern ASP.NET 5 MVC 6通用存储库模式 - ASP.NET 5 MVC 6 Generic Repository Pattern ASP.NET MVC - 如何在存储库模式中单元测试边界? - ASP.NET MVC - How to Unit Test boundaries in the Repository pattern? ASP.NET Web API打破了Repository / Services模式 - ASP.NET Web API breaking Repository/Services pattern 如何将 ASP.NET Core MVC 中的存储库模式与 Entity Framework Core 一起使用? - How to use the repository pattern in ASP.NET Core MVC together with Entity Framework Core?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM