【问题标题】:repository pattern on asp coreasp核心上的存储库模式
【发布时间】:2016-10-29 16:30:39
【问题描述】:

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

所以数据上下文已添加到 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 项目启动.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:无法解决 “Microsoft.EntityFrameworkCore.DbContext”类型的服务,而 试图激活 'On.Store.Repository.Companies.CompanyRepository'。

【问题讨论】:

  • 如果你想要github.com/aguacongas/chatle,我在 GitHub 上提供了一个示例
  • @Abdul,如果解决方案对您有用,请接受您最喜欢的答案。

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


【解决方案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")));

【讨论】:

  • 感谢您的回答.. 问题似乎是对象 DBContext 存在于引用存储库项目的 UI 项目中,因此它不能在存储库项目中使用,因为无法添加 UI 的引用存储库项目..如果有错误请更正:)
  • 您是对的,但是即使您在与存储库相同的项目中有一个自定义 DBContext,它也不会工作,因为当您在 Startup 中配置自定义上下文类时,您需要注入声明上下文类而不是基本 DbContext 类。一会儿我详细解释一下。我将编辑答案...
  • 谢谢您的回答.. 但是asp核心似乎不允许我们从类库项目中创建迁移
  • @Abdul,你一定能做到。请看一下我编辑的答案的第 3) 点。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

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

    例子:

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

    确保将 EntityFramework Tools 注册为项目依赖项并在 project.json 的工具部分中。

    例子:

      {
          "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 应用程序,请将“netcoreapp1.0”框架与以下示例中的其他设置一起添加到 project.json:

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

    要制作桌面 .NET 应用,请确保您的项目目标是“net451”或更新版本(例如“net461”也可以),并确保构建选项“emitEntryPoint”设置为 true。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-08
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多