我想尝试通用,但我遇到了一些问题。
这是我的一步
第 1 步。我创建一个数据库模型也继承类
public class DBRepo { }
public partial class UserAccount : DBRepo
{
public int Id { get; set; }
public string Account { get; set; }
public string Pwd { get; set; }
}
第 2 步。我希望所有 CRUD 操作都可以使用此接口。所以我这样做
public class DBServices
{
public interface IDBAction<TEntity> where TEntity : DBRepo
{
void InsertData(TEntity entity);
}
public class dbCRUD<TEntity> : IDBAction<TEntity> where TEntity : DBRepo
{
private readonly CoreContext _db;
private DbSet<TEntity> dbSet;
public dbCRUD(CoreContext _db)
{
this._db = _db;
this.dbSet = _db.Set<TEntity>();
}
public void InsertData(TEntity _entity)
{
this.dbSet.Add(_entity);
this._db.SaveChanges();
}
}
}
然后我像ServiceProvider
ServiceProvider provider = new ServiceCollection()
.AddSingleton<IDBAction<DBRepo>>()
.BuildServiceProvider();
provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);
我会得到这个错误
无法实例化实现类型....
所以我改变尝试其他方式。
在构造函数中
private readonly IDBAction<DBRepo> dBAction;
public HomeController( IDBAction<DBRepo> _dBAction)
{
this.dBAction = _dBAction;
}
....
this.dBAction.InsertData(_ua);
确定。我再次收到错误
无效操作异常: 无法解析类型...
有些人可以教我如何解决问题吗?
->更新
我试图改变,但它失败了
ServiceProvider provider = new ServiceCollection()
.AddScoped<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
.AddScoped<CoreContext>()
.BuildServiceProvider();
错误与此相同
无法解析类型...
这是我的数据库
文本public virtual DbSet<UserAccount> UserAccount { get; set; }
public CoreContext(DbContextOptions<CoreContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(@"Connection String");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserAccount>(entity =>
{
entity.Property(e => e.Account).IsRequired();
entity.Property(e => e.Pwd)
.IsRequired()
.HasMaxLength(20);
});
}
您以错误的方式注册了它。您必须提供(泛型(的实现,并且还必须注册 DbContext。
ServiceProvider provider = new ServiceCollection()
.AddSingleton<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
.BuildServiceProvider();
provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);
此外,将其注册为单例会导致实体框架的更改跟踪出现问题。所以你应该像这样注册它:
ServiceProvider provider = new ServiceCollection()
.AddScoped<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
.AddScoped<CoreContext>()
.BuildServiceProvider();
provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);
你也可以实现一个真正的泛型,比如
public interface IEntity
{
Guid Id { get; set; }
}
public class DbAction<TEntity> : IDbAction<TEntity> where TEntity: class, IEntity, new()
{
public void InsertData(TEntity entity)
{
...
}
}
现在将其注册为泛型
ServiceProvider provider = new ServiceCollection()
.AddScoped(typeof(IDbAction<>), typeof(DbAction<>))
.AddScoped<CoreContext>()
.BuildServiceProvider();
provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);
小例子,但会起作用。
编辑:
当然,必须将 DbContextOptions 传递给 DbContext,IoC 才能正常工作。
.AddDbContext<CoreContext>(options => options.UseSqlServer("my-conntection-string")); // change provider if necessary, this will only work with MS SQL Server