我的 Windows CE 应用程序中有一个 SQL Server CE 数据库。我可以在服务器资源管理器的项目中看到它(HHS.sdf):
...但是表格的 Columns 文件夹不会扩展;点击它们给了我:
HHS.sdf 的路径属性为:
Data Source=Mobile Device\Program Files\hhs\HHS.sdf
如果路径无效,为什么服务器资源管理器会向我显示数据库?如果我在服务器资源管理器中创建一个新连接(通过从数据连接上下文菜单中选择“添加连接...”),我可以导航到设备上的 .SDF 文件(\Program Files\hhs),在“添加连接”对话框:
...并获得“测试连接成功”的证实。
但是在运行时,当尝试填充其中一个表时:
var dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(Int32)));
dt.Columns.Add(new DataColumn("DeptNumber", typeof(Int32)));
dt.Columns.Add(new DataColumn("DeptName", typeof(string)));
foreach (HHSUtils.Department dept in depts)
{
try
{
dt.Rows.Add(dept.Id, dept.DeptNumber, dept.DeptName);
countAdded++;
}
catch (Exception ex)
{
MessageBox.Show(string.Format("deptId == {0}, deptNumber == {1},
deptName == {2} ({3})", dept.Id, dept.DeptNumber, dept.DeptName, ex.Message));
}
}
// Now move it all into the table
using (var bc = new SqlCeBulkCopy(dataSource))
{
bc.DestinationTableName = "Departments";
bc.WriteToServer(dt);
}
...我在 WriteToServer() 行上得到“源列 'DEPTNUM' 不存在且目标不允许空值”。
在调试器中评估“dt”,我看到 DataSet 属性有一个红色的“错误”图标,并显示“无法评估表达式”;“Site”和“XMLTest”属性也是如此;dataSet(相对于 DataSet)属性为空。
“DEPTNUM”这个词没有出现在客户端源代码中,也没有出现在服务器源代码中......
InventoryItems 表的相同代码在没有错误消息的情况下执行(但列在服务器资源管理器中仍然非常害羞)。
我正在以这种方式创建表格:
// Got this from http://stackoverflow.com/questions/20254214/how-can-i-programmatically-determine-if-a-table-exists-within-a-sql-server-ce-da/20339969?noredirect=1#20339969
public static bool TableExists(SqlCeConnection connection, string tableName)
{
using (var command = new SqlCeCommand())
{
command.Connection = connection;
var sql = string.Format(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '{0}'", tableName);
command.CommandText = sql;
var count = Convert.ToInt32(command.ExecuteScalar());
return (count > 0);
}
}
public static void ConditionallyCreateTables()
{
const string sdfPath = @"\Program Files\hhs\HHS.sdf";
string dataSource = string.Format("Data Source={0}", sdfPath);
if (!File.Exists(sdfPath))
{
using (var engine = new SqlCeEngine(dataSource))
{
engine.CreateDatabase();
}
}
using (var connection = new SqlCeConnection(dataSource))
{
connection.Open();
using (var command = new SqlCeCommand())
{
command.Connection = connection;
// It may be that I'll want to replace "if (!TableExists())" with "if (TableExists())" and then either drop the table in that
// case and recreate it, or delete its contents
if (!TableExists(connection, "InventoryItems"))
{
command.CommandText = "CREATE TABLE InventoryItems (Id nvarchar(50) NOT NULL, PackSize smallint NOT NULL, Description nvarchar(255), DeptDotSubdept numeric, UnitCost numeric, UnitList numeric, UPCCode nvarchar(50), UPCPackSize smallint, CRVId int);";
command.ExecuteNonQuery();
}
if (!TableExists(connection, "Departments"))
{
command.CommandText = "CREATE TABLE Departments (Id int NOT NULL, DeptNum int NOT NULL, DepartmentName nvarchar(255))";
command.ExecuteNonQuery();
}
if (!TableExists(connection, "Subdepartments"))
{
command.CommandText = "CREATE TABLE Subdepartments (Id int NOT NULL, DeptId int NOT NULL, SubdeptId int NOT NULL, DepartmentName nvarchar(255))";
command.ExecuteNonQuery();
}
if (!TableExists(connection, "Redemptions"))
{
command.CommandText = "CREATE TABLE Redemptions (Id int NOT NULL, RedemptionId nvarchar(50), RedemptionItemId nvarchar(50), RedemptionName nvarchar(255), RedemptionAmount numeric, RedemptionDept nvarchar(50), RedemptionSubdept nvarchar(50))";
command.ExecuteNonQuery();
}
}
}
}
[{ }] [{ }] [{ }] [{ }] [{ }] [{ }] [{ }] [{ }] [{ }] [{ }] [{ }] [{ }]
顺便说一句,我得出的结论是(经过 20 年在这个职业盐矿的墙壁上凿开,并成为无数严重程度不同的塌方 [*] 的不幸受害者)计算机程序员要么需要精神错乱(这样您就不会被这一切的乏味所驱使)或绝对不受精神错乱(出于同样的原因);如果您从频谱的任一端开始,您可能会没事的;但是,对于那些处于这种连续性中间的人(我认为他们是普通民众的很大一部分):小心,以免您的感官被压成无形的纸浆或堆积成尖叫(如果被闷住)疯狂。
[*****] 是的,真的,每次挖掘时,我都发现我的手在流血的手里抓着镐。
更新
我通过确保临时表中的列名与 SQL Server CE 表中的列名完全对应来解决“DEPTNUM”错误(根据服务器资源管理器,无论如何都不存在):
var dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(Int32)));
dt.Columns.Add(new DataColumn("DeptNum", typeof(Int32)));
dt.Columns.Add(new DataColumn("DepartmentName", typeof(string)));
然而,正如上面所暗示的,主要难题(帖子的名义问题)仍未解决。
更新 2
让电脑打个盹并“想一想”并没有任何帮助。今天也是如此。将记录添加到 SQL Server CE 表的代码工作正常;只是服务器资源管理器,虽然能够正常连接到手持设备的数据库文件(测试连接成功)看不到文件,还是假装看不到?BTW / AWTTW:我将尽快(明天某个时候)奖励这个。
更新 3
本次测试:
if (!File.Exists(sdfPath))
{
using (var engine = new SqlCeEngine(dataSource))
{
engine.CreateDatabase();
}
}
...失败(未输入条件代码),因此手持/Windows CE 应用程序确实将文件视为在运行时存在。
更新 4
我能够读取和写入表格,所以应用程序肯定可以看到它们;我还可以通过导航到 .SDF 文件来查看手持设备上的表格及其数据;双击 .SDF 文件时调用 SQL Server CE 工具。不过,Visual Studio 2008 中的服务器资源管理器需要唤醒。