C# 使用Hangfire时,Startup.cs抛出中给定的连接字符串无法附加文件,因为数据库错误
我正在我的ASP.NETMVCWeb应用程序中使用Hangfire,它已成功安装。我希望使用与存储数据相同的LocalDb来存储排队作业,以便Hangfire出列和处理。但是,当我在C# 使用Hangfire时,Startup.cs抛出中给定的连接字符串无法附加文件,因为数据库错误,c#,asp.net,connection-string,hangfire,C#,Asp.net,Connection String,Hangfire,我正在我的ASP.NETMVCWeb应用程序中使用Hangfire,它已成功安装。我希望使用与存储数据相同的LocalDb来存储排队作业,以便Hangfire出列和处理。但是,当我在Startp.cs中提供其在Web.config中定义的连接字符串或名称时,我遇到了以下错误。在hangfire之前,我在同一个localDb中添加、删除和更新数据时没有遇到任何问题 Cannot attach the file 'c:\users\jerry_dev\documents\visual studio
Startp.cs
中提供其在Web.config
中定义的连接字符串或名称时,我遇到了以下错误。在hangfire之前,我在同一个localDb中添加、删除和更新数据时没有遇到任何问题
Cannot attach the file 'c:\users\jerry_dev\documents\visual studio 2013\Projects\Hangfire.Highlighter\Hangfire.Highlighter\App_Data\aspnet-Hangfire.Highlighter-20150113085546.mdf' as database 'aspnet-Hangfire.Highlighter-20150113085546'.
Startup.cs:
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.UseHangfire(config =>
{
string hangfireConnectionString = @"Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-Hangfire.Highlighter-20150113085546.mdf;Initial Catalog=aspnet-Hangfire.Highlighter-20150113085546;Integrated Security=True";
config.UseSqlServerStorage(hangfireConnectionString);
config.UseServer();
});
}
我的项目解决方案名为“Hangfire.Highlighter”
Web.config:
数据库是否已创建?你能试着使用不同的conneciton字符串格式吗,
“Server=;Database=HangFire.Highlighter;Trusted_Connection=True;”我知道这是一个老问题,但已经过去9个月了,我也为此大伤脑筋,决定写一篇文章 我的解决方案是创建一个快速且脏的DbContext,将其指向正确的连接字符串,然后在构造函数中调用Database.CreateIfNotExists:
public class HangfireContext : DbContext
{
public HangfireContext() : base("name=HangfireContext")
{
Database.SetInitializer<HangfireContext>(null);
Database.CreateIfNotExists();
}
}
public类上下文:DbContext
{
public HangfireContext():base(“name=HangfireContext”)
{
Database.SetInitializer(null);
CreateIfNotExists();
}
}
在HangfireBootstrapper.Start()方法中,我执行以下操作:
public void Start()
{
lock (_lockObject)
{
if (_started) return;
_started = true;
HostingEnvironment.RegisterObject(this);
//This will create the DB if it doesn't exist
var db = new HangfireContext();
GlobalConfiguration.Configuration.UseSqlServerStorage("HangfireContext");
// See the next section on why we set the ServerName
var options = new BackgroundJobServerOptions()
{
ServerName = ConfigurationManager.AppSettings["HangfireServerName"]
};
_backgroundJobServer = new BackgroundJobServer(options);
var jobStarter = DependencyResolver.Current.GetService<JobBootstrapper>();
//See the Recurring Jobs + SimpleInjector section
jobStarter.Bootstrap();
}
}
public void Start()
{
锁定(锁定对象)
{
如果(启动)返回;
_开始=真;
HostingEnvironment.RegisterObject(this);
//如果数据库不存在,这将创建该数据库
var db=new HangfireContext();
GlobalConfiguration.Configuration.UseSqlServerStorage(“HangfireContext”);
//请参阅下一节,了解设置服务器名的原因
var options=new BackgroundJobServerOptions()
{
ServerName=ConfigurationManager.AppSettings[“HangfireServerName”]
};
_backgroundJobServer=新的backgroundJobServer(选项);
var jobStarter=DependencyResolver.Current.GetService();
//请参见定期作业+简单输入部分
jobStarter.Bootstrap();
}
}
不知道为什么Hangfire在使用LocalDb时会如此困难-也许它只能处理成熟的SQL实例?无论哪种方式,这都适用于我、新的团队成员和新的开发/登台/生产实例。我也知道这是旧的,但最近遇到了它。以下是我的解决方案:
这就解决了我的问题。杰克的回答对我不起作用,因为我遇到了这个问题: 我对其进行了以下修改:
“name=“
”。感谢:UseSqlServerStorage
。因此,我没有将“HangfireContext”
传递给它,而是从虚拟数据库上下文复制连接字符串public class HangfireContext : DbContext
{
public HangfireContext() : base("HangfireContext") // Remove "name="
{
Database.SetInitializer<HangfireContext>(null);
Database.CreateIfNotExists();
}
}
public partial class Startup
{
public static void ConfigureHangfire(IAppBuilder app)
{
var db = new HangfireContext();
GlobalConfiguration.Configuration.UseSqlServerStorage(db.Database.Connection.ConnectionString); // Copy connection string
app.UseHangfireDashboard();
app.UseHangfireServer();
}
}
public类上下文:DbContext
{
public HangfireContext():base(“HangfireContext”)//删除“name=”
{
Database.SetInitializer(null);
CreateIfNotExists();
}
}
公共部分类启动
{
公共静态无效配置hangfire(IAppBuilder应用程序)
{
var db=new HangfireContext();
GlobalConfiguration.Configuration.UseSqlServerStorage(db.Database.Connection.ConnectionString);//复制连接字符串
app.UseHangfireDashboard();
app.UseHangfireServer();
}
}
根据AspNetCore 3.1和Hangfire 1.7.17回答
如果存在具有指定数据库名称的现有数据库,Hangfire应创建所有表。
如果要使用LocalDb,可以使用以下注册(见下文)
同样,请注意连接字符串如何具有必须存在于localdb中的数据库名称(例如:
Hangfire
)。如果您完全删除Database=xxx
参数,它将默认选择主数据库并在那里创建所有表。检查您的App_数据文件夹并确保'aspnet Hangfire.Highlighter-20150113085546'数据库存在。奇怪的是,/App_数据中没有数据库添加它,您应该会没事的。实际上,在我启用之后“显示所有文件”我看到有一个“HighlighterDb.mdf”“将连接字符串更改为指向该字符串,然后!我在App_Data/下没有看到任何数据库。如果数据库不存在,我如何创建它?一个简单而干净的数据库创建解决方案。谢谢。这对我有用,谢谢!但是,Hangfire应该创建db文件。几乎对我有效。如果还有其他人正在为此解决方案而挣扎,请参阅我的答案:
public class HangfireContext : DbContext
{
public HangfireContext() : base("HangfireContext") // Remove "name="
{
Database.SetInitializer<HangfireContext>(null);
Database.CreateIfNotExists();
}
}
public partial class Startup
{
public static void ConfigureHangfire(IAppBuilder app)
{
var db = new HangfireContext();
GlobalConfiguration.Configuration.UseSqlServerStorage(db.Database.Connection.ConnectionString); // Copy connection string
app.UseHangfireDashboard();
app.UseHangfireServer();
}
}
services
.AddHangfire(
(serviceProvider, config) =>
{
//read settings or hardcode connection string, but this is cleaner
var configuration = serviceProvider.GetService<IConfiguration>();
var connectionString = configuration.GetValue<string>("Hangfire:ConnectionString");
var sqlServerStorageOptions =
new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
};
config
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings();
.UseSqlServerStorage(connectionString, sqlServerStorageOptions);
});
"Hangfire": {
"ConnectionString": "Data Source=(localdb)\\MsSqlLocalDb; Database=Hangfire;"
}