我目前正在尝试分发依赖.NET中某种形式的数据库的应用程序。我正在尝试使用SQL Server Express或SQL Server Express LocalDB。
为了访问数据库,我正在使用实体框架。
现在的目标是创建一个可部署的版本,不需要手动对SQL服务器进行任何更改。它需要在启动应用程序时根据需要进行安装和设置。在我的开发计算机上一切顺利。一旦部署到另一台计算机,问题就开始了。
我尝试了LocalDB,以避免在目标计算机上手动设置数据库结构的要求。然而,在启动应用程序时,它报告连接字符串的问题。 attachdbfilename无效。
此文件名设为attachdbfilename=|DataDirectory|\database\Db.mdf
就像我说的。在我的开发机器上这是有效的。在使用已部署的文件和从IDE运行时都是如此。然而目标mashine报告了这个问题。我使用ClickOnce和我的应用程序安装了SQL Server Express 2012 LocalDB。部署的文件包含正确目录中的mdf文件。
完整的连接字符串是:
<connectionStrings>
<add name="DbContainer" connectionString="metadata=res://*/database.DbModel.csdl|res://*/database.DbModel.ssdl|res://*/database.DbModel.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\database\Db.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
我看不出attachdbfilename无效的原因。在目标机器上安装sql server似乎没问题。
我还尝试使用普通的SQL Server 2012 Express表达它。我怎么想如果我想使用它,没有附加的数据库文件我需要手动创建所需的数据库。这不是一种选择。
我在一些问题中读到这表明创建ObjectContext
存在问题,但这个问题也很好看:
Public Partial Class DbContainer
Inherits ObjectContext
Public Sub New()
MyBase.New("name=DbContainer", "DbContainer")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public Sub New(ByVal connectionString As String)
MyBase.New(connectionString, "DbContainer")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
Public Sub New(ByVal connection As EntityConnection)
MyBase.New(connection, "DbContainer")
MyBase.ContextOptions.LazyLoadingEnabled = true
OnContextCreated()
End Sub
...
就像它是由实体框架生成的。
我对如何解决这个问题的想法不足。
答案 0 :(得分:0)
好的问题原来是|DataDirectory|
我使用我使用的正确的单击数据目录手动替换连接字符串中的此条目:
Dim dataDir As String
If ApplicationDeployment.IsNetworkDeployed Then
Dim ad = ApplicationDeployment.CurrentDeployment
dataDir = ad.DataDirectory
Else
dataDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
End If
再加载数据库文件没问题。我不能说为什么替换|DataDirectory|
无法正常工作。对于开发计算机上的版本,这只是替换为空字符串......这是有效的,因为工作目录是引用数据库目录的父目录。
使用ClickOnce时,数据文件(包括数据库)位于不同的目录中。这会导致连接字符串失败。上面的代码修复了这个问题。我无法解释为什么这不是开箱即用的。