【问题标题】:Creating a basic service for CRUD operations为 CRUD 操作创建基本服务
【发布时间】:2021-10-22 19:24:57
【问题描述】:

我编写了以下代码来总结我的 DomainServices 中的所有 CRUD 操作,但它在第一次使用时会引发错误。

// generic class

public class GenericManager<T>  : DomainService where T : class, IEntity<int>
{
    public readonly IRepository<T, int> _genericRepository;

    public async Task<T> GetAsync(int id) => await AsyncExecuter.FirstOrDefaultAsync(_genericRepository.Where(m => m.Id == id));
    public async Task AddAsync(T entity) => await _genericRepository.InsertAsync(entity);
    public async Task AddManyAsync(IEnumerable<T> entities) => await _genericRepository.InsertManyAsync(entities);
    public async Task UpdateAsync(T entity) => await _genericRepository.UpdateAsync(entity);
    public async Task UpdateManyAsync(IEnumerable<T> entities) => await _genericRepository.UpdateManyAsync(entities);
    public async Task DeleteAsync(T entity) => await _genericRepository.DeleteAsync(entity);
}

// my domain services
public class ClientManager : GenericManager<Client>
{
    public async Task<Client> GetClientByNameAsync(string userName) => await AsyncExecuter.FirstOrDefaultAsync(_genericRepository.Where(m => m.UserName == userName));
    public async Task<Client> FindClientWithVKID(string vkid) => await AsyncExecuter.FirstOrDefaultAsync(_genericRepository.Where(m => m.VkId == vkid));
}

// usage my domain service other code
var user = await _clientManager.GetAsync(userId);

但是由于程序的工作,发出这样的错误

System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)
at RenewalTML.Data.ClientManager.GetClientByNameAsync(String userName) in 
C:\Users\Fearp\source\repos\RenewalTML\RenewalTML\Data\User\ClientManager.cs:line 15
at RenewalTML.Data.ClientAuthServices.LoginIsReady(UserLoginModel model) in 
C:\Users\Fearp\source\repos\RenewalTML\RenewalTML\Data\User\ClientAuthServices.cs:line 236
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation 
invocation, IInvocationProceedInfo proceedInfo)
at 
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation 
invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult] 
(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation 
invocation, IInvocationProceedInfo proceedInfo)
at 
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult] 
(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation 
invocation, IInvocationProceedInfo proceedInfo)
at 
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation 
invocation, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope)
at Volo.Abp.Auditing.AuditingInterceptor.ProcessWithNewAuditingScopeAsync(IAbpMethodInvocation 
invocation, AbpAuditingOptions options, ICurrentUser currentUser, IAuditingManager 
auditingManager, IAuditingHelper auditingHelper)
at Volo.Abp.Auditing.AuditingInterceptor.ProcessWithNewAuditingScopeAsync(IAbpMethodInvocation 
invocation, AbpAuditingOptions options, ICurrentUser currentUser, IAuditingManager 
auditingManager, IAuditingHelper auditingHelper)
at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult] 
(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation 
invocation, IInvocationProceedInfo proceedInfo)
at 
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult] 
(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at RenewalTML.Pages.Client.Authorization.LoginExecuted(EditContext editContext) in 
C:\Users\Fearp\source\repos\RenewalTML\RenewalTML\Pages\Client\Authorization.razor:line 227
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task 
task)
at Microsoft.AspNetCore.Components.Forms.EditForm.HandleSubmitAsync()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task 
task)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle) 

我原本预计会出错。如何创建这样一个可行的代码,这样我就不会在我的应用程序中为 CRUD 操作编写相同的代码?

我的用户:.NET 5.0 Blazor Web 服务器,EFCore + mysql Volo.Abp 版本:4.3.3

【问题讨论】:

  • userId 是 int 吗?我没有看到它在哪里声明
  • 那么什么是IRepository,它是如何创建(和销毁)的?等等。所有相关代码都丢失了。
  • @DJ Burb 是整数,它是从页面的 .blazor 字段中读取的
  • @Henk Holterman IRepository - 是 abp.io 框架的一部分 APB.DOMAIN.REPOSITORY docs.abp.io/en/abp/4.4/Repositories

标签: .net model-view-controller entity-framework-core blazor abp


【解决方案1】:

似乎public readonly IRepository&lt;T, int&gt; _genericRepository; 是null,因为您从未初始化它。因此,当在ClientManager 中调用_genericRepository.Where(m =&gt; m.UserName == userName) 时,您会得到一个LINQ 异常,指出source (_genericRepository) 是null。

您可能需要在 ClientManager 的构造函数中通过 DI 容器使用注入的实例初始化 genericRepository。

更新

参考你正在使用的框架的相同文档,这基本上是缺少的部分。

你可能需要这样的东西:

public class ClientManager : GenericManager<Client>
{

    public ClientManager(IRepository<Client, Guid> clientRepository)
    {
        _genericRepository = clientRepository;
    }

    
...

【讨论】:

  • @HenkHolterman 嗯,你是对的......但那行代码无论如何都是粗略的。为什么 OP 在_genericRepository 中执行.Where 操作?也许他/她让IRepository&lt;T, int&gt; 实现了枚举器接口?
  • 在我的其他服务中初始化public class ClientAuthServices : ApplicationService, IClientAuthServices { private readonly ClientManager _clientManager; public ClientAuthServices(ClientManager clientManager) { _clientManager = clientManager; } ...
  • 官方的 abp.io 文档没有说明通用服务,也许 iRepository 不能使用 ' where T: class, IEntity '
  • 如果您不创建 genericRepository,它会起作用,我认为如果您将 genericRepository 的功能继承到其他存储库,它会起作用。
  • 看了你链接的那个库后,我想我的怀疑。问题是您没有初始化 ClientManager 尝试使用的 IRepository。 _genericRepository 为空!为 ClientManager 定义一个构造函数,获取注入的通用存储库实例并将其分配给_genericRepository。 @JigglyDezar
猜你喜欢
  • 2018-12-05
  • 2014-03-08
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多