|数据目录|的位置如何在连接字符串解决?
How is location of |Data Directory| in connection strings resolved?
如果我创建一个 asp.net 项目并使用 entity framework 创建一个数据库,类似这样的内容会自动添加到 web.config
:
中的连接字符串中
<add name="DefaultConnection" connectionString="data source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\WebAppName.mdf;initial catalog=WebAppName;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
请注意,它使用 |Data Directory|
而不是完全限定的文件路径,在本例中,它指向“App_Data”文件夹。 Here's 一些文档如何解释它:
The presence of User Instance=true and AttachDBFilename=|DataDirectory| cause SqlConnectionHelper to conclude that the connection string targets SQL Server Express and triggers the database's creation. (The presence of data source=.\SQLEXPRESS in the connection string does not factor into the decision, because SqlConnectionHelper supports non-default as well as default instances of SQL Server Express.) The |DataDirectory| portion of the connection string specifies that the MDF file is located inthe App_Data directory. SqlConnectionHelper derives the database name from the MDF file name. It also creates an App_Data folder to hold the MDF if the folder doesn't already exist.
除非,如果我在控制台应用程序中使用 Entity Framework,那么 none 是正确的——您只会得到一个异常,说明在指定路径中没有文件,它将忽略您创建的任何 App_Data
个文件夹,并且如果有 none 个文件夹则无法创建。如果您完全删除 AttachDBFilename
部分,它将起作用,但会在 .exe
文件所在的本地输出箱中创建数据库。 Google tells me 您可以使用 AppDomain.SetData
手动设置 |Data Directory|
但显然对于控制台应用程序来说仍然不正确(得到编译错误说 "An object reference is required")。
所以我的问题是,|Data Directory|
的位置究竟是如何解析的?据我所知,控制台应用程序和 Asp.net 应用程序之间的差异意味着解决方案不能仅在 SQL Server Express 中发生,因为两者都使用相同的安装。那么它是否发生在 asp.net 服务器中?或者是否有在 asp.net 个项目中创建的隐藏设置文件?
这是指定 |DataDirectory|
位置的代码
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
internal static string GetDataDirectory() {
if (HostingEnvironment.IsHosted)
return Path.Combine(HttpRuntime.AppDomainAppPath, HttpRuntime.DataDirectoryName);
string dataDir = AppDomain.CurrentDomain.GetData(s_strDataDir) as string;
if (string.IsNullOrEmpty(dataDir)) {
string appPath = null;
#if !FEATURE_PAL // FEATURE_PAL does not support ProcessModule
Process p = Process.GetCurrentProcess();
ProcessModule pm = (p != null ? p.MainModule : null);
string exeName = (pm != null ? pm.FileName : null);
if (!string.IsNullOrEmpty(exeName))
appPath = Path.GetDirectoryName(exeName);
#endif // !FEATURE_PAL
if (string.IsNullOrEmpty(appPath))
appPath = Environment.CurrentDirectory;
dataDir = Path.Combine(appPath, HttpRuntime.DataDirectoryName);
AppDomain.CurrentDomain.SetData(s_strDataDir, dataDir, new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDir));
}
return dataDir;
}
如果我创建一个 asp.net 项目并使用 entity framework 创建一个数据库,类似这样的内容会自动添加到 web.config
:
<add name="DefaultConnection" connectionString="data source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\WebAppName.mdf;initial catalog=WebAppName;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
请注意,它使用 |Data Directory|
而不是完全限定的文件路径,在本例中,它指向“App_Data”文件夹。 Here's 一些文档如何解释它:
The presence of User Instance=true and AttachDBFilename=|DataDirectory| cause SqlConnectionHelper to conclude that the connection string targets SQL Server Express and triggers the database's creation. (The presence of data source=.\SQLEXPRESS in the connection string does not factor into the decision, because SqlConnectionHelper supports non-default as well as default instances of SQL Server Express.) The |DataDirectory| portion of the connection string specifies that the MDF file is located inthe App_Data directory. SqlConnectionHelper derives the database name from the MDF file name. It also creates an App_Data folder to hold the MDF if the folder doesn't already exist.
除非,如果我在控制台应用程序中使用 Entity Framework,那么 none 是正确的——您只会得到一个异常,说明在指定路径中没有文件,它将忽略您创建的任何 App_Data
个文件夹,并且如果有 none 个文件夹则无法创建。如果您完全删除 AttachDBFilename
部分,它将起作用,但会在 .exe
文件所在的本地输出箱中创建数据库。 Google tells me 您可以使用 AppDomain.SetData
手动设置 |Data Directory|
但显然对于控制台应用程序来说仍然不正确(得到编译错误说 "An object reference is required")。
所以我的问题是,|Data Directory|
的位置究竟是如何解析的?据我所知,控制台应用程序和 Asp.net 应用程序之间的差异意味着解决方案不能仅在 SQL Server Express 中发生,因为两者都使用相同的安装。那么它是否发生在 asp.net 服务器中?或者是否有在 asp.net 个项目中创建的隐藏设置文件?
这是指定 |DataDirectory|
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
internal static string GetDataDirectory() {
if (HostingEnvironment.IsHosted)
return Path.Combine(HttpRuntime.AppDomainAppPath, HttpRuntime.DataDirectoryName);
string dataDir = AppDomain.CurrentDomain.GetData(s_strDataDir) as string;
if (string.IsNullOrEmpty(dataDir)) {
string appPath = null;
#if !FEATURE_PAL // FEATURE_PAL does not support ProcessModule
Process p = Process.GetCurrentProcess();
ProcessModule pm = (p != null ? p.MainModule : null);
string exeName = (pm != null ? pm.FileName : null);
if (!string.IsNullOrEmpty(exeName))
appPath = Path.GetDirectoryName(exeName);
#endif // !FEATURE_PAL
if (string.IsNullOrEmpty(appPath))
appPath = Environment.CurrentDirectory;
dataDir = Path.Combine(appPath, HttpRuntime.DataDirectoryName);
AppDomain.CurrentDomain.SetData(s_strDataDir, dataDir, new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDir));
}
return dataDir;
}