【发布时间】:2020-11-11 02:50:25
【问题描述】:
目标
我正在尝试在 ASP.NET Core Web 应用程序和其他项目/解决方案之间共享一个类库,并且该类应该能够与调用进程/环境正在使用的任何数据库进行交互。
问题
我有一个类库在我的 ASP.NET Core 3.1 Web 应用程序中使用时抛出了一个奇怪的错误。类库实际上在前端(网站)和后端应用程序之间共享,负责处理一些重复的、重负载的过程。我在前端和后端都使用 EF Core,并且数据库在 Azure 上,不是我的本地计算机。然而,当网络应用程序尝试做一些工作时,我收到以下错误:
尝试为文件 C:...\bin\Debug\netcoreapp3.1\aspnetdb.mdf 附加自动命名数据库失败。存在同名数据库,或指定文件无法打开,或位于 UNC 共享上。
这对我来说根本没有意义,因为数据库位于 Azure 上。此外,使用后端应用程序在库中调用相同的方法不会引发此错误。连接字符串存储在网站的appsettings.json 和后端的app.config 中。
这是引发错误的代码块,但这仅在 ASP.NET Core 项目上的SaveChanges() 调用中发生:
public static void AddLogEvent(int Severity, DateTime EventTime, string EventType, string User, string Message)
{
DBEntities context = new DBEntities();
DbSet<LogEvent> dbSet = context.Set<LogEvent>();
LogEvent NewRecord = new LogEvent();
NewRecord.Id = Guid.NewGuid();
NewRecord.Severity = Severity;
NewRecord.EventTime = EventTime;
NewRecord.EventType = EventType;
NewRecord.User = User;
NewRecord.Message = Message;
dbSet.Add(NewRecord);
context.SaveChanges();
}
在DBEntities 中,我将覆盖OnConfiguring() 方法,以确保在任何环境下都能正确连接:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
bool FoundValidConnection = false;
if (ConfigurationManager.ConnectionStrings.Count > 0)
{
foreach (ConnectionStringSettings connstr in ConfigurationManager.ConnectionStrings)
{
if (FoundValidConnection == false)
{
if (string.Compare(connstr.Name.Trim().ToUpper(), "DefaultConnection".ToUpper()) == 0)
{
optionsBuilder.UseSqlServer(connstr.ConnectionString);
FoundValidConnection = true;
break;
}
}
}
foreach (ConnectionStringSettings connstr in ConfigurationManager.ConnectionStrings)
{
if (FoundValidConnection == false)
{
if (string.Compare(connstr.Name.Trim().ToUpper(), "DBEntities".ToUpper()) == 0)
{
optionsBuilder.UseSqlServer(connstr.ConnectionString);
FoundValidConnection = true;
break;
}
}
}
if (FoundValidConnection == false)
{
//if still haven't found one of the expected connection string names, then take whatever the first one is.
optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings[0].ConnectionString);
FoundValidConnection = true;
}
}
else
{
//nothing to do. there are no connection strings in the ConfigurationManager
}
}
}
最后,当我在网站上单步调试时,我可以看到位于ConfigurationManager.ConnectionStrings 的唯一连接字符串是 1,名称为LocalSqlServer,连接字符串设置为:
data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
这似乎是我的本地测试 SQLExpress 实例,但未在网络应用程序的任何地方使用。 SQLExpress 中本地测试数据库的所有引用或连接字符串都已被删除,所以我很困惑这是如何显示的,而 appsettings.json 中的那个被忽略了。我也不明白 optionsBuilder.IsConfigured 如何在 Web 应用程序上返回 FALSE。我希望已经配置了该上下文。
【问题讨论】:
-
我希望已经配置了该上下文 - 当您使用无参数构造函数 (
= new DBEntities();) 时,它从未配置过。当你使用 DI 或有一个带有DbContextOptions参数的构造函数时,它将被配置,该参数是外部配置的。 -
好的,感谢您提供的信息。这有点帮助,但我不确定这与网络应用程序抛出的错误有何关系,这似乎与它甚至不应该知道存在的完全不同的数据库有关。我不确定为什么 Web 应用程序的 ConfigurationManager.ConnectionStrings 集合只包含我什至没有在 appsettings.json 中设置的那个集合。我不知道它是从哪里来的,也不知道它为什么要使用它。
-
这与 EF Core 无关,是您必须弄清楚的事情。首先,
ConfigurationManager变量是什么,它来自哪里以及如何初始化。 -
您似乎正在使用来自
System.Configuration的ConfigurationManager,它仅适用于app.config文件。对于 .Net Core 应用程序 (appsettings.json),您需要一种不同的方法。见stackoverflow.com/questions/39083372/… -
感谢您为我指明了正确的方向。当我弄清楚时,我会跟进并提交答案与他人分享。似乎依赖注入可能是要走的路。
标签: c# asp.net-core entity-framework-core