Kiz*_*mar 5 c# entity-framework-core asp.net-core
使用一个WebApi
项目和一个Data
包含实体框架实现的单独项目来处理DotNetCore 解决方案。我们一直在升级库,所以我们使用了所有最新的 Core 东西。
在Data
项目中,我们创建了一个ApplicationDbContextFactory
以创建迁移(需要一个无参数的构造函数)。由于添加迁移时的无参数构造函数约束,您无法通过注入IOptions<>
轻松访问appsettings.json
值。我们最终使用 aConfigurationBuilder
来拉入WebApi
'sappsettings.json
文件。
我们最近更改了ApplicationDbContextFactory
也拉入user-secrets
。这允许每个开发人员使用自定义连接字符串,而不必忽略文件或记住不要提交某些内容。
由于进行了此更改,因此dotnet ef migrations add MIGRATION_NAME
在命令行中使用效果很好。但是,add-migration MIGRATION_NAME
在 Visual Studio 的包管理器控制台中使用现在似乎被破坏并出现以下错误:
add-migration : 使用“1”参数调用“Substring”的异常:“StartIndex 不能小于零。参数名称:startIndex” At line:1 char:1 + add-migration TESTING + ~~~~~~ ~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Add-Migration], MethodInvocationException +fullyQualifiedErrorId : ArgumentOutOfRangeException,Add-Migration
我尝试了该命令的一些变体,以查看它是否需要指定上下文(除其他外),但似乎没有任何方法可以解决此错误。它似乎永远不会超过ApplicationDbContextFactory
.
这是我所指的代码:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Models.Domain.Settings;
using System;
using System.Diagnostics;
namespace Data
{
public class ApplicationDbContextFactory : IDbContextFactory<ApplicationDbContext>
{
private readonly SolutionSettings _settings;
// In order to use 'add-migration' in Visual Studio, you have to have a parameterless constructor.
// Otherwise you get "No parameterless constructor defined for this object." when creating a migration.
public ApplicationDbContextFactory()
{
}
public ApplicationDbContextFactory(IOptions<SolutionSettings> settings)
{
_settings = settings.Value;
}
public ApplicationDbContext Create(DbContextFactoryOptions options)
{
// If the IOptions signature was hit, we can just pull the dbconnection from settings
if (_settings != null && _settings.DbConnection != null)
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer(_settings.DbConnection, opts => {
opts.EnableRetryOnFailure();
opts.MigrationsAssembly("Data");
});
return new ApplicationDbContext(optionsBuilder.Options);
}
else
{
// Otherwise, we have to get the settings manually...
return Create(options.ContentRootPath, options.EnvironmentName);
}
}
private ApplicationDbContext Create(string basePath, string environmentName)
{
// HACK: To pull from WebApi\appsettings.json
basePath = basePath.Replace("Data", "WebApi");
Console.Write($"PATH & ENV: {basePath}, {environmentName}" + Environment.NewLine);
// Pull in the WebApi\appsettings.json files, apply user secrets
var builder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environmentName.ToLower()}.json", optional: true, reloadOnChange: true)
// This needs to match the UserSecretsId value in the WebApi.csproj
// Also added a UserSecretsId key with the same value to Data.csproj to suppress a warning
// Adding this was the only way it would actually override values with user-secret values
.AddUserSecrets("USER_SECRETS_ID")
.AddEnvironmentVariables();
var config = builder.Build();
var connectionString = config["SolutionSettings:DbConnection"];
Console.Write($"CONNECTION STRING: {connectionString}" + Environment.NewLine);
return Create(connectionString);
}
private ApplicationDbContext Create(string connectionString)
{
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentException(
$"{nameof(connectionString)} is null or empty.",
nameof(connectionString));
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer(connectionString, options => {
options.EnableRetryOnFailure();
options.MigrationsAssembly("Data");
});
return new ApplicationDbContext(optionsBuilder.Options);
}
}
}
Run Code Online (Sandbox Code Playgroud)
作为旁注;在对此进行故障排除时,我添加了opts.EnableRetryOnFailure();
和opts.MigrationsAssembly("Data");
,但我不知道它们在这种情况下有什么不同。
我的问题:
自从你发布它以来已经很长时间了,但我刚刚遇到了这个错误并找出了原因(尽管它没有任何意义)
问题出在线路上
console.Write($"CONNECTION STRING: {connectionString}" + Environment.NewLine);
Run Code Online (Sandbox Code Playgroud)
如果您在 CONNECTION STRING 之后删除冒号,它就可以工作。我不知道为什么插值中的冒号会导致此错误
归档时间: |
|
查看次数: |
1767 次 |
最近记录: |