当我们在 Asp.Net MVC Core 中创建 Controller 时,IdentityUser 通用存储库

IdentityUser generic repository when we create Controller in Asp.Net MVC Core

这是存储库模式,通常如果我使用 ContextDb 而不是 IdentityContextDb ,它会起作用但我必须使用 Indentity创造我的身份。

Core.Repository

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;



namespace XYZ.CORE.Repository
 {
     public class Repository<TEntity, TContext> : IRepository<TEntity> where 
 TEntity : class, new() where TContext : IdentityDbContext, new()
     {
         public void Delete(TEntity entity)
         {
             using (var context=new TContext())
             {
                 var deleteEntity = context.Entry(entity);
                 deleteEntity.State = EntityState.Deleted;
                 context.SaveChanges();
             }
         }

     public IEnumerable<TEntity> GetAll(Expression<Func<TEntity, bool>> filter = null)
    {
        using (var context = new TContext())
        {
            return filter == null ? context.Set<TEntity>().AsEnumerable() : context.Set<TEntity>().Where(filter).AsEnumerable();
        }
    }

    public TEntity GetById(int id)
    {
        using (var context = new TContext())
        {
            return context.Set<TEntity>().Find(id);
        }
    }

    public void Insert(TEntity entity)
    {
        using (var context = new TContext())
        {
            var addEntity = context.Entry(entity);
            addEntity.State = EntityState.Added;
            context.SaveChanges();
        }
    }

    public void Update(TEntity entity)
    {
        using (var context = new TContext())
        {
            var updatedEntity = context.Entry(entity);
            updatedEntity.State = EntityState.Modified;
            context.SaveChanges();
        }
    }
}
}

再次但是 :) 当我从 IdentityContextDb 继承我的上下文时,它需要类似此行底部的通用类型及其存储库问题。

当我们调用这个 Repo 时,我将分享类似错误的内容

DAL.Context

using XYZ.DATA.Entity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;

namespace XYZ.DAL.Context
{
   public class XyzDb:IdentityDbContext<AppUser>
    {
        public HysWebDb(DbContextOptions options) : base(options)
        {

        }

    }
}

现在让我们调用 Controller

UI.Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using XYZ.UI.Models.VM;
using Microsoft.AspNetCore.Mvc;
using XYZ.DAL.Context;
using Microsoft.AspNetCore.Identity;
using XYZ.DATA.Entity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;
using XYZ.CORE.Repository;

namespace XYZ.UI.Controllers.Account
{
     //[Authorize(Roles ="Admin")]
    public class RegisterController : Controller
    {
        private readonly XyzDb _database;
        private readonly UserManager<AppUser> _uManager;
        private readonly Repository<AppUser,XyzDb> _userRepo;
        public RegisterController(UserManager<AppUser> uManager, XyzDb database)
        {
            _database = database;
            _uManager = uManager;

        }
   }

}

虽然我们还没有注射但是...

Error CS0311 The type 'XYZ.DAL.Context.XyzDb' cannot be used as type parameter 'TContext' in the generic type or method 'Repository'. There is no implicit reference conversion from 'XYZ.DAL.Context.XyzDb' to 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext'. ~\XYZ.UI\Controllers\Account\RegisterController.cs 21 Active

Error CS0310 'XyzDb' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TContext' in the generic type or method 'Repository' ~\XYZ.UI\Controllers\Account\RegisterController.cs 21 Active

Line 21 is here private readonly Repository _userRepo;

谢谢,

厄兹古尔

实际上您是在对通用存储库设置约束 class

public class Repository<TEntity, TContext> : IRepository<TEntity> where
TEntity : class, new() where TContext : IdentityDbContext, new()

这是您的 IdentityDbContext 上的 new(),因此您的 IdentityDbContext 应该包含一个无参数构造函数。 有关详细信息,请查看 Microsoft 文档 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-constraint

 public class Repository<TEntity, TContext> : IRepository<TEntity> where 
 TEntity : class, new() where TContext : IdentityDbContext, new()

你在这里定义了两件事:

  1. 存储库 class 必须使用 class 那里 TEntity 和 TContext 有 new() 这意味着无参数构造函数,而实际上你只有 1 个带选项的构造函数 - (这是你的第二个错误)

public HysWebDb(DbContextOptions options) : base(options)

  1. 第二个问题不是 100% 确定,但是如果你继承了一个通用接口但声明了类型 - IdentityDbContext - 它不能被认为只是 IdentityDbContext

public class XyzDb:IdentityDbContext < AppUser>

要解决您的问题,您应该将 public class 存储库更改为:

 public class Repository<TEntity, TContext> : IRepository<TEntity> where 
 TEntity : class, new() where TContext : IdentityDbContext<AppUser>

我可以通过在构造函数中使用上下文引用和注入来解决

public class Repository<T> : IRepository<T> where T : class { private readonly ContextX _database; public Repository(ContextX database) { _database = database; }

我们找不到其他解决方法

谢谢,

厄兹居尔德尼兹