如何使用DI在Entity Framework中使用通用CRUD

时间:2018-03-16 08:25:41

标签: c# generics asp.net-core

我想尝试通用但我遇到了一些问题。

这是我的步骤

步骤1.我创建了一个数据库模型也继承类

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <parameters>true</parameters>
            </configuration>
        </plugin>

第2步。我希望所有CRUD操作都可以使用此界面。所以我这样做

    public class DBRepo { }
    public partial class UserAccount : DBRepo
    {
        public int Id { get; set; }
        public string Account { get; set; }
        public string Pwd { get; set; }
    }

然后我像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);

确定。我再次收到错误

  

InvalidOperationException:无法解析类型...

的服务
有些人可以教我如何解决这个问题吗?

- &GT;更新

我尝试改变,但它失败了

private readonly IDBAction<DBRepo> dBAction;
public HomeController( IDBAction<DBRepo> _dBAction)
{
   this.dBAction = _dBAction;
}

....
this.dBAction.InsertData(_ua);

错误相同

  

无法解决类型...

的服务

这是我的DBContext

ServiceProvider provider = new ServiceCollection()
                            .AddScoped<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
                            .AddScoped<CoreContext>()
                                .BuildServiceProvider();

1 个答案:

答案 0 :(得分:1)

您正在以错误的方式注册它。您必须提供(通用)的实现,并且必须注册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