asp核心上的存储库模式

时间:2016-10-29 16:30:40

标签: asp.net entity-framework asp.net-core

我们首先尝试使用ef代码开发asp核心应用程序(MVC)。但似乎需要db上下文是可执行文件而不是类库。

所以数据上下文已添加到Web UI项目中,但问题是如何在存储库项目中使db上下文的dbset可用..

示例代码如下:

public class CompanyRepository : GenericRepository<Company>, /*IGenericRepository<Company>*/ ICompanyRepository
{ 
public CompanyRepository(DbContext dbContext) : base(dbContext)
{ 
}
public async Task<IEnumerable<Company>> GetAllAsync()
{
return await base.GetAllAsync<Company>();
}
}

MVC Project StartUp .cs

services.AddDbContext<DBContext>();
services.AddScoped<ICompanyRepository, CompanyRepository>();

MVC项目中的DBCOntext.cs

 public class DBContext : DbContext
 {
        private IConfigurationRoot _config;
        public DBContext(IConfigurationRoot config, DbContextOptions options):base(options)
        {
            _config = config;
        }
 }

目前似乎引发了以下错误:

  

处理请求时发生未处理的异常。 InvalidOperationException:无法解析   类型为&#39; Microsoft.EntityFrameworkCore.DbContext&#39;的服务而   试图激活   &#39; On.Store.Repository.Companies.CompanyRepository&#39;

3 个答案:

答案 0 :(得分:1)

我们在这里有两个问题:

1)在Startup类中配置服务时,您正在配置自定义上下文(为了便于参考,我们将其命名为CustomDbContext):

public class CustomDbContext: DbContext
{

...并在Startup类中:

services.AddDbContext<CustomDbContext>();

...所以在你的知识库中,你需要注入一个声明的类的上下文,而不是基本的DbContext类:

// THIS WILL NOT WORK
public class CompanyRepository : GenericRepository<Company>, ICompanyRepository
{ 
    public CompanyRepository(DbContext dbContext) : base(dbContext)
    { 
    }
}


// THIS WILL WORK
public class CompanyRepository : GenericRepository<Company>, ICompanyRepository
{ 
    public CompanyRepository(CustomDbContext dbContext) : base(dbContext)
    { 
    }
}

2)问题二是直接从第一个问题中揭示出来的。因此,您在MVC项目中声明了CustomDbContext,因此不能在引用的存储库项目中使用。因此解决方案似乎很简单,您需要将CustomDbContext移出MVC项目(要么存储库项目,要么可以由MVC和存储库引用的任何其他/第三个项目)。通过这种方式,您可以在Startup类中轻松配置CustomDbContext,并在存储库中使用此上下文。

3)从外部库注册上下文,您可以使用MigrationsAssembly方法轻松完成,它将如下所示:

services.AddDbContext<CustomDbContext>(options => options.UseSqlServer(
            _configuration.GetConnectionString("YourConnectionStringName"),
            b => b.MigrationsAssembly("YourExternalAssemblyName")));

答案 1 :(得分:0)

这是一个非常简单的项目,可以帮助您和其他开发人员。 Generic Repository Pattern in ASP.NET Core

答案 2 :(得分:-1)

这解决了您无法使用迁移命令行工具的原始问题,并允许您保持适当的图层分离。

这是一个已知问题(已跟踪here),目前有两种解决方法,直接取自EntityFramework Core documentation

  

解决方法1 - 使用单独的启动项目

     

将类库项目转换为“app”项目。这可以是.NET Core应用程序,也可以是桌面.NET应用程序。

     

示例:

 {
     "frameworks": {
         "netcoreapp1.0": {
             "dependencies": {
                 "Microsoft.NETCore.App": {
                     "type": "platform",
                     "version": "1.0.0-*"
                 }
             }
         }
     }
 }
     

请务必将EntityFramework工具注册为项目依赖项,并在project.json的tools部分中注册。

     

示例:

  {
      "dependencies": {
          "Microsoft.EntityFrameworkCore.Tools": {
              "version": "1.0.0-preview2-final",
              "type": "build"
          }
      },
      "tools": {
          "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
      }
  }
     

最后,指定一个“可运行的应用程序”的启动项目。

     

示例:

     

dotnet ef --startup-project ../MyConsoleApplication/ migrations list

     

解决方法2 - 将您的类库修改为启动应用程序

     

将类库项目转换为“app”项目。这可以是.NET Core应用程序,也可以是桌面.NET应用程序。

     

要使项目成为.NET Core App,请将“netcoreapp1.0”框架添加到project.json以及下面示例中的其他设置:

  {
      "buildOptions": {
          "emitEntryPoint": true
      },
      "frameworks": {
          "netcoreapp1.0": {
              "dependencies": {
                  "Microsoft.NETCore.App": {
                      "type": "platform",
                      "version": "1.0.0-*"
                  }
              }
          }
      }
  }
     

要制作桌面.NET应用程序,请确保将项目目标“net451”或更新(例如“net461”也可用)并确保构建选项&#34; emitEntryPoint&#34;设置为true。

  {
      "buildOptions": {
          "emitEntryPoint": true
      },
      "frameworks": {
          "net451": { }
      }
  }