SQL Compact 3.5 的小技巧和陷阱!
一篇详细介绍在桌面应用程序中使用 SQL Compact 3.5 时遇到的奇怪问题及解决方案的文章。
引言
与其写一篇常见的代码演示文章,我更想写一些关于如何使用 Microsoft SQL Compact 3.5 的笔记。在最近的一个项目中,我遇到了一些问题,花了一段时间才弄明白,主要是因为文档不清晰或者根本没有!对于桌面应用程序来说,这是一个非常棒的软件包,我相信它会越来越受开发人员欢迎,不仅仅是针对移动应用程序。显然,许多开发人员会选择使用 SQL Express,它也是一个很棒的工具,但也有一些注意事项。首先,与 Compact 3.5 相比,安装和分发使用 SQL Express 的应用程序可能会复杂得多。对于我的情况,主要要求之一是让应用程序安装过程尽可能简单,并拥有一个“进程内”运行的完全正常工作的数据库解决方案。
在规划我当前的应用程序时,我偶然发现了一篇非常好的文章,详细比较了 SQL Compact 3.5 和 SQL Express,可以在这里找到。这在最初决定方向时真的很有帮助。SQL Compact 3.5 确实缺少一些非常基本的 SQL Server 功能,例如存储过程,这对某些人来说将是一个真正的障碍。
设计数据库
显然,您首先要做的就是亲自动手设计您的 SQL Server Compact 数据库……现在,提供程序在哪里????这让我困惑了一段时间,因为我可以用 Visual Studio 2008 制作 *.sdf 文件,但它们似乎不是 3.5 版本的数据库!嗯?好吧,您需要安装设计工具!默认情况下,Visual Studio 安装过程会安装 SQL Server Compact 3.5,但它不会安装允许您创建 3.5 版本数据库的设计时工具。您可以从安装光盘中获取这些工具;文件名为 SSCEVSTools-enu.msi,此文件也包含在 Visual Studio 的 Express 版本中。
SQL Compact 和 LINQ (SQLMetal)
正如您可能期望的,LINQ 是受支持的;这是一个很大的话题,在这里讨论实在超出范围,此外 Matt Sollars 已经在 CodeProject 上做了一项出色的工作,您可以在这里阅读。
不幸的是,SQL Compact 与 Visual Studio 内置的 Visual O/R Mapping 功能不兼容,因此要生成驱动 LINQ 所需的 .dbml 文件,SQLMetal.exe 是唯一的选择。我在项目中关于 LINQ 的做法是,将 SQLMetal.exe 复制到我的解决方案目录中并将其添加到源代码管理。然后,我创建了一个简单的批处理文件,以便在数据库结构发生变化时运行。这样,我可以确保新生成的代码类将与解决方案兼容,并且如果您处于多开发人员环境中,每个人都以相同的方式生成 .dbml 文件。我的特定批处理文件如下所示:
SqlMetal /database:DB /Pluralize /provider:SQLCompact /code:"DB.cs" /language:csharp
"DataBase\DB.sdf" /Password:dbpass1! /entitybase:AppName.DataLayer.ITable
SqlMetal /database:DB /Pluralize /provider:SQLCompact /dbml:DB.dbml "DataBase\DB.sdf"
/namespace:AppName.DataLayer /Password:dbpass1!
SqlMetal /database:DB /provider:SQLCompact /code:"DB.cs" /map:DB.xml "DataBase\DB.sdf"
/Password:dbpass1!
sqlmetal /?
PAUSE
这里有一点需要注意,除非您想要一个 XML 映射文件,否则您实际上不需要创建代码文件(批处理文件第一行中的 .cs 命令)。当您在解决方案中包含 .dbml 文件时,Visual Studio 将自动生成您的类。这使得处理数据库结构的变化有点麻烦。例如,如果您向 Compact 数据库添加了一些字段或表;为了更新解决方案中的类,您必须删除当前的 .dbml,使用您的批处理文件重新创建它,然后包含新的 .dbml 文件,这将使 Visual Studio 弹出并执行其操作,并创建类(在 C# 或 VB 中)。如果您还在构建 XML 映射文件(以及批处理文件中所需的代码文件),请记住删除 SQLMetal 构建的 .cs 文件,否则您的解决方案代码中将包含重复的部分类,这将导致构建错误。
连接字符串 / CreateDatabase()
这让我困惑了好几天。任何开发软件的人都会知道任何硬编码的东西,尤其是数据库连接字符串的可怕之处。在我的应用程序中,我使用标准方式来告诉应用程序数据库所在的位置,即在解决方案的属性中使用 |DataDirectory| 宏
Data Source=|DataDirectory|\DataBase\DB.sdf;Password=dbpass1!;Persist Security Info=True
一切都很顺利,直到您开始包含旨在保护应用程序在发布后万无一失的类。显然,针对桌面设计的断开连接的数据库应用程序需要内置弹性。首先,您不希望随应用程序附带空的数据库文件;它应该足够智能,在启动时(安装后的首次运行)动态创建一个,或者在后续应用程序运行中使用现有数据库。如果您正在使用 LINQ,有一个很棒的方法叫做……您猜对了……
CreateDatabase():
太棒了!我心想。嗯,算是吧。它确实有效!然而,当使用此方法时,您不能在连接字符串中使用 |DataDirectory| 宏。SQL Compact 3.5 中有一个 bug,导致此功能失效。您必须提供一个完全限定的连接字符串,此方法才能工作。这没什么大不了的,但这个 bug 似乎没有很好的文档,而且对于一个在实际应用中否则会非常非常有用的方法来说,这确实是一个致命缺陷。为了解决这个问题,您只需使用类似以下代码:
AppLocation = AppDomain.CurrentDomain.BaseDirectory;
DatabaseLocation = Path.Combine(AppLocation, "Database");
PathToDatabase = Path.Combine(DatabaseLocation, "DB.sdf");
我将这些定义在一个单独的类中,在那里我存储所有这些应用程序范围的零碎东西,以便应用程序中的任何内容都可以轻松访问它们。因此,在调用 DatabaseExists() 或 CreateDatabase() 方法之前,您需要在主上下文类中构建合格的连接字符串,如下所示:
static DB _context;
_context = new DB("Data Source=" + ApplicationUtilities.DatabaseLocation +
"\\DB.sdf;Password=dbpass1!;Persist Security Info=True");
if (!_context.DatabaseExists())
{
try
{
_context.CreateDatabase();
DatabaseCreated = true;
log.Info("Database created successfully");
}
catch (Exception ex)
{
throw new DBDatabaseException("Failed to Create the Database!", ex);
}
}
else
{
DatabaseCreated = false;
}
私人安装
与 SQL Express 相比,使用 SQL Compact 3.5 的一个主要优势是它非常小巧!!无论从哪个角度看,1.8MB 对于一个数据库解决方案来说都非常小。与 SQL Express 的安装程序相比,它要小几个数量级。另一个主要(恕我直言)的优点是终端用户安装的简便性(以及开发安装程序的简便性!!),因为它只是一个 XCopy 过程,将 DLL 文件从您的 MSI 或 Setup.exe 文件复制到您的安装文件中,然后我们就可以愉快地开始了。我严格按照微软的说明对 SQL Compact 3.5 进行私人安装,但它没有成功;之后我无数次地检查它们,但都没有运气。我最终找到了解决方案……您需要将以下内容添加到您的 app.config 文件中:
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.3.5" />
<add name="Microsoft SQL Server Compact Data Provider"
invariant="System.Data.SqlServerCe.3.5"
description=".NET Framework Data Provider for Microsoft SQL Server Compact"
type="System.Data.SqlServerCe.SqlCeProviderFactory,
System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=89845dcd8080cc91"/>
</DbProviderFactories>
</system.data
我还没有在微软网站上找到这些信息,这肯定不是他们关于如何进行 SQL Compact 3.5 私人安装的说明的一部分。
就这些了,伙计们
目前,这几乎是我想要涵盖的所有内容。我希望这能帮助其他人使用 SQL Compact 3.5,我会在发现任何应该在这里的东西时更新这篇文章。
历史
- 2008 年 8 月 1 日 - 初始版本。