在注入仓储的时候,找到了获得默认仓储实现类型的方法,可以看到这里它使用的是 DefaultRepositoryDbContextType 作为默认的 TDbContext 类型。
protected virtual Type GetDefaultRepositoryImplementationType(Type entityType) { var primaryKeyType = EntityHelper.FindPrimaryKeyType(entityType); // 重点在于构造仓储类型时,传递的 Options.DefaultRepositoryDbContextType 参数,这个参数就是后面 EfCoreRepository 的 TDbContext 泛型。 if (primaryKeyType == null) { return Options.SpecifiedDefaultRepositoryTypes ? Options.DefaultRepositoryImplementationTypeWithoutKey.MakeGenericType(entityType) : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType); } return Options.SpecifiedDefaultRepositoryTypes ? Options.DefaultRepositoryImplementationType.MakeGenericType(entityType, primaryKeyType) : GetRepositoryType(Options.DefaultRepositoryDbContextType, entityType, primaryKeyType); }最后我发现这个就是在模块调用 AddAbpContext<TDbContext> 所提供的泛型参数。
public abstract class AbpCommonDbContextRegistrationOptions : IAbpCommonDbContextRegistrationOptionsBuilder { // ... 其他代码 protected AbpCommonDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) { OriginalDbContextType = originalDbContextType; Services = services; DefaultRepositoryDbContextType = originalDbContextType; CustomRepositories = new Dictionary<Type, Type>(); ReplacedDbContextTypes = new List<Type>(); } // ... 其他代码 } public class AbpDbContextRegistrationOptions : AbpCommonDbContextRegistrationOptions, IAbpDbContextRegistrationOptionsBuilder { public Dictionary<Type, object> AbpEntityOptions { get; } public AbpDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) : base(originalDbContextType, services) // 之类调用的就是上面的构造方法。 { AbpEntityOptions = new Dictionary<Type, object>(); } } public static class AbpEfCoreServiceCollectionExtensions { public static IServiceCollection AddAbpDbContext<TDbContext>( this IServiceCollection services, Action<IAbpDbContextRegistrationOptionsBuilder> optionsBuilder = null) where TDbContext : AbpDbContext<TDbContext> { // ... 其他代码。 var options = new AbpDbContextRegistrationOptions(typeof(TDbContext), services); // ... 其他代码。 return services; } }所以,我们的默认仓储的 dbContextKey 是 XXXDbContext,我们的自定义仓储继承 EfCoreRepository<IXXXDbContext,TEntity,TKey> ,所以它的 dbContextKey 就是 IXXXDbContext 。所以自定义仓储获取到的 DbContext 就与自定义仓储的不一致了,从而提示上述异常。
解决找到自定自定义仓储的定义,修改它 EfCoreReposiotry<TDbContext,TEntity,TKey> 的 TDbContext 泛型参数,变更为 XXXDbContext 即可。
public class EfCoreStudentRepository : EfCoreRepository<XXXDbContext, Student, long>, IStudentRepository { public EfCoreStudentRepository(IDbContextProvider<XXXDbContext> dbContextProvider) : base(dbContextProvider) { } public Task<int> GetCountWithStudentlIdAsync(long studentId) { return DbSet.CountAsync(x=>x.studentId == studentId); } }