无法使SQL Server Compact 3.5 / 4与ASP .NET MVC 2一起工作

22

我正在使用Visual Studio 2008 Pro。

可能我很明显地错过了什么,但是我一直在尝试在我的asp.net mvc应用程序中使用Sql Server Compact 4的CTP。我几乎找不到有关如何设置此项或工作示例应用程序的任何指令。我的目标是进行私人安装,以便我可以将其包含在我的Web应用程序中,而无需在我的域主机上进行Sql Server设置。这只是我自己瞎搞,试图弄清楚这个问题。我不打算使用这个进行市场推广或其他任何事情。

所以,我复制了所有安装在基础4.0方向(c:\Program Files\Sql Server compact\v4.0)的dll文件到我的应用程序中的一个lib文件夹中。我将复制到输出方向选项设置为“仅在新建时复制”。然后我引用了System.Data.SqlServerCE dll并将“复制本地”设置为True。

我通过Sql Studio Express创建了一个sdf文件。值得注意的是,我没有看到创建此文件的CE 4.0版本的选项,因此它是使用CE 3.5创建的。我创建了一些表,在这些表中添加了一些行,然后将*.sdf文件复制到我的App_Data目录。值得一提的是,从VS 2008内部,此文件从未出现在我的项目中,但它确实存在于App_Data目录的物理位置中。我不确定这是为什么。

接下来,我只是尝试通过以下方式对我的sdf文件进行基本连接:

SqlCeConnection conn = new SqlCeConnection("DataSource=rpg.sdf");

这将产生以下错误:

Unable to load the native components of SQL Server Compact corresponding to the ADO.NET provider of version 8402. Install the correct version of SQL Server Compact. Refer to KB article 974247 for more details.

我认为从这里开始,我只需尝试让 Sql CE 3.5 起作用。我将本地的 Sql CE 3.5 升级到 SP2,并复制位于基本位置 (c:\Program Files\Sql Server compact\v3.5) 的 DLL,包括从我的项目引用中删除和重新添加 System.Data.SqlServerCE DLL 的版本。

奇怪的是,当我右键单击并查看所引用的 SqlServerCE DLL 的属性时,它总是显示版本 4.0.0.1。

各位,我真的需要一些指导。我已经在 stack overflow、帮助文档、在线书籍和谷歌上搜索了很久,但没有找到任何从 CE 3.5 或 4.0 的最基础开始,并告诉我要添加哪些 DLL,放置在哪里,如何引用它们,如何将 .sdf 文件添加到我的项目中,连接到它并从其中查询的内容。我确实找到了几个提到 IBuySpy 门户样例应用程序应该使用 Sql CE 3.5 的地方,但实际上无法通过 MSDN 下载迷宫进行导航。理想情况下,我想为 CE 4.0 设置一个私有部署。

我听取任何建议,观点或其他信息将不胜感激。谢谢!

是的,我确实看到了 KB。它没有帮助

请在此处查看:http://support.microsoft.com/kb/974247

CORFLAG 的结果

好的,我尝试过了,这是我的结果: C:\Development\Mvc2MessingAround\Mvc2MessingAround\bin\Lib>corflags System.Data.SqlServerCe.dll Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8 Copyright (c) Microsoft Corporation. All rights reserved。

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 9
ILONLY    : 1
32BIT     : 0
Signed    : 1

我本想安装Sql CE 3.5/4的x86版本。由于我的处理器能够运行64位,但我运行的是Windows xp sp3 32位系统,所以安装程序可能会有些混乱。结果似乎表明它是64位的。是否是这种情况?

添加细节

到目前为止,以下配置在两台机器上进行了尝试。两者都是Windows xp sp3 32位,具有64位处理器。两个开发环境都是VS 2008 Pro。第二台机器上的结果是在安装Sql CE 4 Ctp后出现的。

配置 #1

myapp\bin\
     System.Data.SqlServerCe.dll

myapp\bin\private
    amd64
    x86
    
myapp\bin\private\x86
    sqlceca40.dll
    sqlcecompact40.dll
    sqlceer40EN.dll
    sqlceme40.dll
    sqlceqp40.dll
    sqlcese40.dll
    
myapp\bin\private\amd64
    sqlceca40.dll
    sqlcecompact40.dll
    sqlceer40EN.dll
    sqlceme40.dll
    sqlceqp40.dll
    sqlcese40.dll

错误:

An exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.DLL but was not handled in user code

Additional information: Unable to load the native components of SQL Server Compact corresponding to the ADO.NET provider of version 8402. Install the correct version of SQL Server Compact. Refer to KB article 974247 for more details.

代码:

SqlCeConnection conn = new SqlCeConnection();

配置2

与#1相同,但System.Data.SqlServerCE.Entity.dll位于myapp\bin目录下。

在执行上述代码之前,页面出现错误。这是消息:

无法加载文件或程序集“System.Data.SqlServerCe.Entity”或其某个依赖项。该程序集是由比当前加载的运行时更新的运行时构建的,因此无法加载。

描述:在当前 Web 请求的执行期间,发生未经处理的异常。请检查堆栈跟踪以获取有关错误的更多信息,以及错误在代码中的起源。

异常详细信息:System.BadImageFormatException: 无法加载文件或程序集“System.Data.SqlServerCe.Entity”或其某个依赖项。该程序集是由比当前加载的运行时更新的运行时构建的,因此无法加载。

我已经检查了VS 2008 Pro中的项目设置,将.NET 3.5框架设置为目标。

配置3

与#1相同,只是从myapp\bin\private文件夹引用System.Data.SqlServerCE.dll。

结果与配置#1相同(错误消息完全相同,并且错误发生在相同的代码行上)。

正确的配置

按照Erik的说明(如果我更仔细地遵循了它们),设置应该是

myapp\bin
    x86
    amd64
    System.Data.SqlServerCE.dll

将System.Data.SqlServerCE.dll直接引用到bin文件夹中的代码中。 我的错误是认为需要包含Private文件夹,但实际上不需要。 除非您使用的是.net 4.0解决方案,否则不要将System.Data.SqlServerCE.Entity.dll放在bin文件夹中。 我认为该dll不适用于3.5。

有用的链接:

Link


System.Data.SqlServerCe.dll 是任意 CPU... - ErikEJ
使用配置3时,没有Entity.dll文件。目录结构错误!请将以下目录内容(包括x86和amd64文件夹)复制到ASP.NET应用程序的bin文件夹中:C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private。在你的asp.net bin文件夹下不应该有“Private”文件夹。 在你的bin文件夹下,有一个x86和一个amd64文件夹,每个文件夹都有正确的文件。 - ErikEJ
这也发生在VS 2010和ASP.NET MVC 3 Beta中。 - Jedidja
如果您知道自己的架构,那么您只需要x86或amd64其中之一。此外,如果更加简洁的话,您可以将所有的dll文件放在输出文件夹中(通过移动x86文件夹中的dll文件并删除该文件夹)。 - nawfal
嗨,配置在Windows 7/8/10中完美运行,但在Windows XP中不行。对于这种情况有什么想法,我会非常感激。 - Jorge Omar Sanchez
6个回答

31

SQL CE 3.5不能与ASP.NET一起使用,你必须使用4.0 CTP。

这里下载。

安装运行时环境。

将以下目录内容(包括x86和amd64文件夹)复制到ASP.NET应用程序的bin文件夹中: C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private

更新:使用“桌面”文件夹中的System.Data.SqlServerCe.dll以避免发生中等信任问题

myapp\bin\ 
 System.Data.SqlServerCe.dll 

myapp\bin\x86 
 sqlceca40.dll 
 sqlcecompact40.dll 
 sqlceer40EN.dll 
 sqlceme40.dll 
 sqlceqp40.dll 
 sqlcese40.dll 

myapp\bin\amd64 
 sqlceca40.dll 
 sqlcecompact40.dll 
 sqlceer40EN.dll 
 sqlceme40.dll 
 sqlceqp40.dll 
 sqlcese40.dll 

在/bin文件夹中添加对刚放入的 System.Data.SqlServerCe.dll 文件的引用。

将 SQL Compact sdf 文件放置在 App_Data 文件夹中。

添加连接字符串:

<connectionStrings>
   <add name ="NorthWind"
   connectionString="data source=|DataDirectory|\Nw40.sdf" />
</connectionStrings>

连接!:-)

using System.Data.SqlServerCe;

    protected void Page_Load(object sender, EventArgs e)
    {
        using (SqlCeConnection conn = new SqlCeConnection())
        {
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
            conn.Open();
            using (SqlCeCommand cmd = new SqlCeCommand("SELECT TOP (1) [Category Name] FROM Categories", conn))
            {
                string valueFromDb = (string)cmd.ExecuteScalar();
                Response.Write(string.Format("{0} Time {1}", valueFromDb, DateTime.Now.ToLongTimeString()));
            }
        }
    }

1
我已经按照你在这里提出的建议做了一切。但是每当我尝试创建一个新的SqlCEConnection对象时,仍然会收到相同的错误消息:“无法加载与版本8402的ADO.NET提供程序对应的SQL Server Compact的本机组件。安装正确版本的SQL Server Compact。有关更多详细信息,请参阅KB文章974247。”我已清理了我的临时文件,退出了VS 2008,清理了项目,重新构建等等。你有什么想法吗? - jason
是的,它将在与您的处理器架构环境变量对应的文件夹中查找未托管的DLL,即x86或amd64。 - ErikEJ
1
请按照我的步骤一步一步来。没有“lib”文件夹,只需将SQLCE文件夹复制到您的bin文件夹中即可。当然,您不能使用3.5文件与4.0一起使用,可以使用WebMatrix或http://sqlcecmd.codeplex.com创建一个4.0版本的文件。 - ErikEJ
@ErikEJ,你说“更新:使用桌面文件夹中的System.Data.SqlServerCe.dll以避免中等信任问题”,但它的版本与“私有”文件夹中的版本不同!对我来说,在Windows窗体桌面应用程序中正常工作的唯一dll是在私有文件夹中的那个。 - S.Serpooshan
原始问题涉及Web应用程序,而不是桌面应用程序。对于桌面应用程序,您可以使用私人文件夹中的文件。 - ErikEJ
显示剩余11条评论

13

如果你使用的连接字符串中包含 providerName ,而且你还没有安装 SDK,则还需要将其添加到 web.config(或 app.config)中。

  <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845dcd8080cc91" culture="neutral"/>
        <bindingRedirect oldVersion="4.0.0.0-4.0.0.1" newVersion="4.0.0.1"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SqlServerCe.4.0"/>
      <add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
    </DbProviderFactories>
  </system.data>

注意:如果您安装了SDK,则需要执行“remove”操作,因为它会将此信息放入您的machine.config文件中。


4
谢谢!这解决了我一直在解决的问题。但是为什么它能起作用呢?在我的系统上,System.Data.SqlServerCe.dll的版本号为4.0.8435.1,而你的bindingRedirect目标为4.0.0.0-4.0.0.1。那么为什么这种情况下bindingRedirect甚至会影响到情况呢?我很高兴它能起作用,但我不明白为什么。你能为我澄清一下吗? - Scott Bussinger
仅供参考@ScottBussinger:我认为您可以跳过<runtime>元素,在<DbProviderFactories>上使用4.0.0.0。如果您在后者上使用4.0.0.1,则需要添加绑定。 - Grimace of Despair

2

好的,既然您在寻求解决方案,那我猜一下。请运行corflags.exe在您复制到引用目录中的程序集上。您是为哪种类型的计算机构建的?如果您正在64位计算机上编译为x64或任何CPU,请确保corflags告诉您您的引用不仅限于32位。也许它正回退到您的GAC中的错误版本。如果它告诉您所引用的程序集只有32位,请将您的项目编译为32位项目或找到DLL的64位版本。


1
如果您正在使用NuGet安装SQL CE提供程序,则最简单的解决方案是添加一个后构建步骤,从NuGet包的NativeBinaries文件夹中复制这些文件。

这个答案听起来很有道理,但我不理解它。你能否请加上必要的后构建步骤的示例? - ChrisW
1
将DLL从packages文件夹复制到bin文件夹中,使用https://dev59.com/MUbRa4cB1Zd3GeqPz2Iz中描述的技术。 - Dale Anderson

0
关键是意识到在私有目录(C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private)中的 System.Data.SqlServerCe.Entity.dll 版本为 4.0.0.1,而桌面目录下(C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Desktop\System.Data.SqlServerCe.Entity)的版本为 4.0.0.0。私有目录中的 System.Data.SqlServerCe.dll 版本为 4.0.0.0。
我认为微软分发更新的 SqlServerCe.Entity.dll 却没有相应更新 SqlServer.dll 是个错误。

2
私有目录中 System.Data.SqlServerCe.dll 的汇编版本为 4.0.0.1! - ErikEJ
我赞同Erik的观点。如果您想要使用私人CE实例部署,您需要将项目链接到位于私人目录中的System.Data.SqlServerCe.dll版本4.0.0.1。这样做是为了避免在更新SQLCE时出现问题。 - Jonx

0
我构建了一个asp.net web api并将其托管在Azure上,但在使用sql server compact时遇到了一些问题。我通过以下步骤解决了这个问题: 首先删除所有system.data.sqlserverce.dll和任何使用它的dll,然后 安装这两个包:

Install-Package SqlServerCompact 然后重新构建

Install-Package EntityFramework.SqlServerCompact -Version 4.3.6 然后重新构建

之后,它就可以正常工作了。同时,安装任何依赖于system.data.sqlserverce.dll的NuGet包也都能很好地工作。 希望这能帮助到某些人。 reference


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接