当我们在 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()
你在这里定义了两件事:
- 存储库 class 必须使用 class 那里 TEntity 和 TContext 有 new() 这意味着无参数构造函数,而实际上你只有 1 个带选项的构造函数 - (这是你的第二个错误)
public HysWebDb(DbContextOptions options) : base(options)
- 第二个问题不是 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;
}
我们找不到其他解决方法
谢谢,
厄兹居尔德尼兹
这是存储库模式,通常如果我使用 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()
你在这里定义了两件事:
- 存储库 class 必须使用 class 那里 TEntity 和 TContext 有 new() 这意味着无参数构造函数,而实际上你只有 1 个带选项的构造函数 - (这是你的第二个错误)
public HysWebDb(DbContextOptions options) : base(options)
- 第二个问题不是 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;
}
我们找不到其他解决方法
谢谢,
厄兹居尔德尼兹