【问题标题】:In what format does SqlCeConnection expect its connection string arg?SqlCeConnection 期望它的连接字符串 arg 采用什么格式?
【发布时间】:2014-05-02 23:43:59
【问题描述】:

我调用了失败的 SqlCeConnection.Open()。我收到的异常消息非常通用:“System.Data.SqlserverCe.SqlCeException”(比漂亮更通用)

相关代码为:

private DBConnection()
{
    try
    {
        string conStr = "Data Source = " + filename;
        string cmpStr = conStr + ".tmp";
        if (File.Exists(filename+".tmp"))
            File.Delete(filename+".tmp");

        engine = new SqlCeEngine(conStr);

        if (File.Exists(filename))
        {
        }
        else
        {
            engine.CreateDatabase();

            }
        engine.Dispose();

        objCon = new SqlCeConnection(conStr);                                                                           
            //MessageBox.Show(string.Format("conStr == {0}", conStr)); 
        objCon.Open(); // <= This is where all Dallas breaks loose; conStr is "DataSource = \My Documents\NRPSDB.SDF" (which file *does* exist on the device)
    }
    catch(Exception ex)
    {
        NRPS.ExceptionHandler(ex, "DBConnection.DBConnection");
    }
}

问题是传递给 SqlCeConnection 构造函数的连接字符串 arg 吗? “DataSource =”序言是否不必要/有问题? backwhacks 是否需要加倍或分配给逐字字符串?还是……???

更多信息请见this scintillating exchange

更新

Grant Winney 的答案看起来很有希望,但今天尝试一下,我发现它在我的(Windows CE / CF)情况下无法编译。我遵循“SpecialFolder”的可能性是:

ApplicationsData
Favorites
Personal
Programs
StartMenu
Startup

这些都不对应“我的文档”吗?

更新 2

对以下 ctacke 评论的扩展回复:

这里是 SqlCe 异常嵌入 MessageBox.Show()“调试”字符串的地方:

public static string GetFormTitle(string formName, string serialNo, string siteNo)
{
    MessageBox.Show(string.Format("GetFormTitle() reached. formName == {0}; serialNo == {1}; siteNo == {2}", formName, serialNo, siteNo)); // TODO: Remove after testing
    string titleBar = formName == "" ? "NRPS HHS" : formName;

我最终看到的是:

“GetFormTitle() 已到达。formName == NRPS: System.Data.SqlServerCe.SqlCeException; serialNo == ; siteNo == ;”

一个相关的帖子/线程是here

更新 3

bizarro 自定义异常处理程序确实会尝试显示异常详细信息,如下所示:

public static void ExceptionHandler(Exception ex, string location)
{
    try
    {
        MessageBox.Show("Exception: " + ex.Message + "\n\nLocation: " + location, GetFormTitle("NRPS: " + ex.GetType().FullName,"",""));
    }
    catch(Exception exc)
    {
        MessageBox.Show("Exception Handler generated an exception!\n" + exc.Message + "\n\nCalling Location: " + location, GetFormTitle("NRPS: " + exc.GetType().FullName,"",""));
    }
}

更新 4

现在我们可能正在取得进展。我注释掉了自定义异常处理程序中调用 GetFormTitle() 的现有行并将其替换为:

MessageBox.Show(string.Format("location: {0}; Exception: {1}; Inner Exception: {2}; TypeFullName: {3}; StackTrace: {4}" + location, ex.Message, ex.InnerException, ex.GetType().FullName, ex.StackTrace));

这是我现在看到的:

"位置:DBConnection.DBConnection:

异常:数据库版本不兼容。如果这是兼容文件,请运行修复。对于其他情况,请参阅文档。 [数据库版本=0,请求版本=0,文件名=我的文档\HHSDB.SDF];

内部异常:TypeFullName:System.Data.SqlServerCe.SqlCeException;

堆栈跟踪: 在 System.Data.SqlServerCe.SqlCeConnection.ProcessResults(Int 32 hr) 在 System.Data.SqlServerCe.SqlCeConnection.Open(boolean silent) 在 System.Data.SqlServerCe.SqlCeConn... [看不到更多... ]*"

这让我印象深刻: 数据库版本 = 0,请求的版本 = 0

但是……Hec Ramsey 是什么?!?

更新 5

这变成了一个新问题,我发布了here

更新 6

那一个到另一个,即here

【问题讨论】:

  • 您遇到的实际异常是什么?如果带有设置的CreateDatabase() 调用成功,则表明它是一个有效的连接字符串,并且您还有其他问题。
  • 这很奇怪:MessageBox.Show() 中嵌入了一个异常。具体来说是:“[我的废话] System.Data.SqlServerCe.SqlCeException; [我的废话的更多]”
  • SqlCeException 通常也包含一个 InnerException。您上面的错误文本表明您的消息框调用中有一个错误,这让我认为您收到的异常不是您上面发布的确切代码。
  • 将代码放入异常处理程序中。让它输出异常。不要尝试在其他地方进行,因为那只是在小麦中添加谷壳。当您使用它时,请确保数据库文件未标记为只读且未设置密码。
  • 您将使用密码创建它(例如,从 PC 复制时)。这是一个空的数据库吗?它是在哪里创建的?如果它是在桌面或其他设备上创建的,如果 SQL CE 版本不同,您可能会遇到问题。

标签: c# database-connection sql-server-ce connection-string windows-ce


【解决方案1】:

如错误文本所示,问题在于 SDF 文件是由与应用程序引用的 SQL Compact 版本不匹配的 SQL Compact 版本创建的。我不会关注报告的版本号,只是它知道存在不匹配的事实。

如果您不知道 SDF 的版本,您可以随时look it up by reading a few bytes from the SDF file

SQL Compact 数据库文件并非 100% 可传输。您绝对不能从较新版本中获取 SDF 并使用较旧的运行时集加载它。

如果数据库是使用 3.1 创建的,您可以通过调用 SqlCeEngine.Upgrade() 将其升级到 3.5。

您不能以编程方式从 1.0 或 2.0 升级到任何更新的版本。您必须使用较旧的 SQL Compact 库与数据库进行交互,或者您必须针对较新的运行时重新创建数据库。

如果数据库是在 PC 上创建的,第一次使用将强制重新索引,因为设备上的索引格式不同。如果数据库中有大量数据,通常最好确保您部署到设备的内容实际上是上次在设备上打开的,以防止用户不得不等待重新索引。

【讨论】:

  • “如错误文本所示,问题在于 SDF 文件是由与应用程序引用的 SQL Compact 版本不匹配的 SQL Compact 版本创建的。”这对我来说似乎很奇怪,因为数据库文件是由一个单独的安装应用程序以编程方式创建的(我在设备上运行它,然后在“我的文档”文件夹中创建 SDF 文件)。实际上,我只是查看了它们,发现两个 SDF 文件的日期为 2014 年 4 月 30 日(当我冷启动设备,然后运行该设置实用程序时),一个日期为 2009 年 1 月 1 日(??? )。无论如何,被引用的是新的
  • 很遗憾,该链接的下载链接已过时或伪造。是否可以将文件复制到我的 PC 上,然后使用 .NET Reflector 或其他类似的工具来窥探“偏移 16 处的位置并在那里读取 32 位 int”。
  • 这变成了一个新问题,我在这里发布:stackoverflow.com/questions/23481551/…
【解决方案2】:

由于filename 包含相对路径"\My Documents\NRPSDB.SDF",您的程序可能会从您的应用程序运行的目录开始查找该路径,这很可能是错误的位置。比如:

...\bin\debug\我的文档\NRPSDB.SDF

尝试将其放入您的方法中,看看它是否能够找到该文件:

string conStr = string.Concat("Data Source = ",
   Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                "NRPSDB.SDF"));

如果它能够找到它,那么无论您从哪里调用该方法,您都必须使用它,以便filename 包含正确的绝对 路径。


关于您使用 Win CE 的更新,SpecialFolder.MyDocuments 的等效项是 SpecialFolder.Personal

来自MSDN

个人。用作文档公共存储库的目录。此成员等同于 MyDocuments。

【讨论】:

  • 不,它肯定在运行它的手持设备上的“\My Documents\NRPSDB.SDF”中。不过,我会试试你的建议(星期一) - 谢谢!
  • 这不是相对路径。它以斜线开头,使其绝对。它不会在 ...\bin\debug... 中查找,因为它在设备上运行。
  • 我们没有足够的信息让我知道错误,虽然我有几个怀疑
  • Grant 的“Environment.SpecialFolder.Personal”提示确实有效,因为它可以引用“我的文档”文件夹;这就是为什么我将其标记为问题的答案。但更新 2 证明了这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 2011-04-04
  • 1970-01-01
  • 2010-12-28
  • 2012-05-04
  • 1970-01-01
相关资源
最近更新 更多