使用| DataDirectory |时,“不支持URI格式”异常在Entity Framework连接字符串中

时间:2012-10-03 13:34:16

标签: entity-framework connection-string datadirectory

我在Visual Studio 2012中有一个单元测试项目,我在其中存储SQL Server 2012的AdventureWorks MDF文件(该文件名为AdventureWorks2012_Data.mdf)。在Visual Studio Server Explorer中,我可以在数据连接中添加MDF并浏览数据库。右键单击$ / Data Connections / AsventureWorks2012_Data.mdf并选择属性,我可以访问连接字符串,如下所示:

Data Source =(LocalDB)\ v11.0; AttachDbFilename = C:\ Projects \ Common \ Source \ Framework \ Framework.Data.Tests \ AdventureWorks2012_Data.mdf; Integrated Security = True; Connect Timeout = 30

我将其复制到app.config文件中的Entity Framework连接字符串中,如下所示:

<!-- Works :-) -->
<connectionStrings>
  <add name="AdventureWorksEntities" 
       connectionString="metadata=res://*/Repository2Tests.AdventureWorks.csdl|res://*/Repository2Tests.AdventureWorks.ssdl|res://*/Repository2Tests.AdventureWorks.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Projects\Common\Source\Framework\Framework.Data.Tests\AdventureWorks2012_Data.mdf;Integrated Security=True;Connect Timeout=30App=EntityFramework&quot;" 
       providerName="System.Data.EntityClient" />
</connectionStrings>

请注意,AttachDbFilename包含MDF文件的完整路径,如下所示: C:\项目\共同\源\框架\ Framework.Data.Tests \ AdventureWorks2012_Data.mdf

当我运行单元测试时,一切都如预期的那样好。

我按照“ADO.NET Entity Framework Connection Strings”中的描述将AttachDbFilename更改为| DataDirectory | \ AdventureWorks2012_Data.mdf,然后按照“ADO.NET |DataDirectory| where is this documented?”中的说明设置DataDirectory,以便我的连接字符串现在如下: / p>

<!-- Doesn't work :-( -->
<connectionStrings>
  <add name="AdventureWorksEntities" 
       connectionString="metadata=res://*/Repository2Tests.AdventureWorks.csdl|res://*/Repository2Tests.AdventureWorks.ssdl|res://*/Repository2Tests.AdventureWorks.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\AdventureWorks2012_Data.mdf;Integrated Security=True;Connect Timeout=30;App=EntityFramework&quot;" 
       providerName="System.Data.EntityClient" />
</connectionStrings>

使用| DataDirectory |的更改导致以下运行时错误:

System.Data.EntityException: The underlying provider failed on ConnectionString. ---> System.ArgumentException: URI formats are not supported.
HResult: -2147024809
at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength)
at System.IO.Path.GetFullPath(String path)
at System.Data.Common.ADP.GetFullPath(String filename)
at System.Data.Common.DbConnectionOptions.ExpandDataDirectory(String keyword, String value, String& datadir)
at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
at System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
at System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
at System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
at System.Data.EntityClient.EntityConnection.ChangeConnectionString(String newConnectionString)
--- End of inner exception stack trace ---
HResult: -2146233087
at System.Data.EntityClient.EntityConnection.ChangeConnectionString(String newConnectionString)
at System.Data.Entity.Internal.LazyInternalConnection.TryInitializeFromAppConfig(String name, ConnectionStringSettingsCollection connectionStrings)
at System.Data.Entity.Internal.LazyInternalConnection.Initialize()
at System.Data.Entity.Internal.LazyInternalConnection.get_ConnectionHasModel()
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Internal.Linq.InternalSet`1.Create()

我已经研究了这几天了,并尝试了无数变化而没有成功。我甚至调试了Microsoft代码,但是通过编译器优化,我无法在堆栈上看到任何调试信息。

是否有人遇到过这个具体问题?

1 个答案:

答案 0 :(得分:3)

当我开始向Microsoft提交错误报告并处理复制步骤时,我终于解决了这个问题。

长话短说,问题出在设置DataDirectory的代码中:

AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory);

问题是我的dataDirectory变量初始化为file://C:/myfolder/etc/而不是C:\myfolder\etc\。我纠正了对此负责的代码并解决了问题。顺便提一下,我使用的代码是:

// in the test assembly initializer
String dataDirectory = AppDomain.CurrentDomain.GetApplicationPath();
AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory);

// GetApplicationPath calls into the following extension method
/// <summary>
/// Defines a set of extension methods on <see cref="AppDomain"/> objects.
/// </summary>
public static class AppDomainExtensions
{
    /// <summary>
    /// Gets the application path (works for both ASP.NET and unit tests).
    /// </summary>
    /// <returns></returns>
    public static string GetApplicationPath(this AppDomain appDomain)
    {
        string binPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        return binPath.Substring(0, binPath.LastIndexOf("bin", StringComparison.InvariantCultureIgnoreCase));
    }
}