首页 > 解决方案 > 如何使用 ef 核心和干净的架构调用存储过程

问题描述

使用 asp.net ef 核心、干净的架构、存储库/服务和 uow 模式

考虑到不应该在存储库类中进行插入,另一方面在服务层我们不能直接调用 dbContext 假设我们想在项目的某些部分使用存储过程或原始查询,

例如,我们想做下面链接中所说的

https://www.entityframeworktutorial.net/faq/how-to-set-explicit-value-to-id-property-in-ef-core.aspx

或调用通过 Database.ExcecuteSqlCommand 执行插入的存储的 Precedure

我们如何在不干扰架构的情况下做到这一点? 我们应该在哪里调用SP?

我的项目架构与本教程非常相似

存储库模式正确完成


编辑:更多说明:这是用户存储库类的添加方法:

 public class UserRepository : IUserRepository
{
    private readonly tablighkadeDbContext _dbContext;

    public UserRepository(tablighkadeDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task Add(User user)
    {
            Entities.User newUser = new Entities.User
            {
                
                Email = user.Email,
                ...
            };
           await _dbContext.AddAsync(newUser);          
    }

unitOfWork 类中的 CompeleteAsync 方法:

 public async  Task<int> CompeleteAsync()
    {
        return await _dbContext.SaveChangesAsync();
    }

最后我在核心层有服务类,我坚持这样的实体:

 public async Task RegisterUser(UserAddVM userAddVM)
    {           
        
        var user = await _unitOfWork.Users.GetByEmail(userAddVM.Email);
        if (user != null)
        {
         //...
        }             
        else {
            var u = new User
            {
                Email = userAddVM.Email,
                //...               
            };
           await _unitOfWork.Users.Add(u);
           await _unitOfWork.CompeleteAsync();              
        }
        
    }

但我不知道如何使用存储过程来做同样的事情,

考虑到我们不应该根据本文和我阅读的其他一些文章在存储库类中保存/更新实体

https://programmingwithmosh.com/net/common-mistakes-with-the-repository-pattern/

标签: stored-proceduresentity-framework-coreclean-architecture

解决方案


您可以扩展通用 EFRepository 类以拥有自己的实现。您应该通过接口公开此实现。

这是 OrderRepository 的示例:https ://github.com/dotnet-architecture/eShopOnWeb/blob/master/src/Infrastructure/Data/OrderRepository.cs

在这个例子中,他们实现了 GetByIdWithItemsAsync(int id),同样你可以有自己的实现。

您可以在 UserRepository 中添加方法。如果您的插入逻辑在存储过程中,那么您不需要使用_dbContext.SaveChanges(). 提交将发生在不受您控制的存储过程中。要刷新状态,您可以在存储过程的末尾选择插入的实体,它应该更新持久实体。

public async Task Add(User user)
{
    var user = _dbContext.Users.SqlQuery("dbo.AddUser @p0 ", user.Name).Single();
}

推荐阅读