首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用DI在实体框架中使用通用CRUD

如何使用DI在实体框架中使用通用CRUD
EN

Stack Overflow用户
提问于 2018-03-16 08:25:40
回答 1查看 303关注 0票数 1

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

这是我的第一步

步骤1.创建一个数据库模型(也是继承类)

代码语言:javascript
复制
    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操作都可以使用这个接口。所以我做了这个

代码语言:javascript
复制
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就像

代码语言:javascript
复制
ServiceProvider provider = new ServiceCollection()
                               .AddSingleton<IDBAction<DBRepo>>()
                               .BuildServiceProvider();
        provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);

我会得到这个错误

无法实例化实现类型。

所以我换了另一种方式。

在构造器中

代码语言:javascript
复制
private readonly IDBAction<DBRepo> dBAction;
public HomeController( IDBAction<DBRepo> _dBAction)
{
   this.dBAction = _dBAction;
}

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

当然,我又犯了错误

InvalidOperationException:无法解析类型为.

有一些能教我怎么解决这个问题吗?

->更新

我试着去改变,但是它失败了

代码语言:javascript
复制
ServiceProvider provider = new ServiceCollection()
                            .AddScoped<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
                            .AddScoped<CoreContext>()
                                .BuildServiceProvider();

错误与此相同

无法解析类型的服务.

这是我的DBContext

代码语言:javascript
复制
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);
            });
        }
EN

回答 1

Stack Overflow用户

发布于 2018-03-16 08:36:18

你注册的方式不对。您必须提供您(泛型)的实现,并且必须注册DbContext。

代码语言:javascript
复制
ServiceProvider provider = new ServiceCollection()
                               .AddSingleton<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
                               .BuildServiceProvider();

 provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);

同时,将其注册为单例也会导致实体框架更改跟踪方面的问题。所以你应该这样注册:

代码语言:javascript
复制
ServiceProvider provider = new ServiceCollection()
                               .AddScoped<IDBAction<DBRepo>, dbCRUD<DBRepo>>()
.AddScoped<CoreContext>()
                                   .BuildServiceProvider();

 provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);

您还可以实现这样一个真正的泛型

代码语言:javascript
复制
public interface IEntity
{
   Guid Id { get; set; }
}

public class DbAction<TEntity> : IDbAction<TEntity> where TEntity: class, IEntity, new()
{
    public void InsertData(TEntity entity)
    {
        ...
    }
}

现在将其注册为泛型

代码语言:javascript
复制
ServiceProvider provider = new ServiceCollection()
                               .AddScoped(typeof(IDbAction<>), typeof(DbAction<>))
.AddScoped<CoreContext>()
                                   .BuildServiceProvider();

 provider.GetService<IDBAction<DBRepo>>().InsertData(_ua);

很小的例子,但会起作用。

编辑:

当然,DbContextOptions必须传递给DbContext,这样IoC才能工作。

代码语言:javascript
复制
.AddDbContext<CoreContext>(options => options.UseSqlServer("my-conntection-string")); // change provider if necessary, this will only work with MS SQL Server
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49316089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档