为什么这个 SQLite Insert 失败了?
Why is this SQLite Insert failing?
我有这段代码可以在 Windows CE / Compact Framework 应用程序的 SQLite 数据库中插入 1..N 条记录:
void IPlatypusDBUtils.SaveSiteMappingData(IEnumerable<SiteMapping> siteMappings)
{
ExceptionLoggingService.Instance.WriteLog("Reached TestPlatypusDBUtils.SaveSiteMappingData");
IEnumerable<SiteMapping> siteMaps = siteMappings;
try
{
using (SQLiteConnection conn = new SQLiteConnection(PlatypusUtils.GetDBConnection()))
{
conn.Open();
foreach (SiteMapping sm in siteMaps)
{
using (SQLiteCommand cmd = new SQLiteCommand(conn))
{
cmd.CommandText =
@"INSERT INTO SiteMapping (Id, SiteNumber, LocationNumber, SiteName) VALUES (@Id, @SiteNumber, @LocationNumber, @SiteName)";
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.Id));
cmd.Parameters.Add(new SQLiteParameter("SiteNumber", sm.SiteNumber.ToString())); // or Platypusconsts.currentsitenum ?
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.LocationNumber));
cmd.Parameters.Add(new SQLiteParameter("SiteName", sm.SiteName));
cmd.ExecuteNonQuery();
} // using (SQLiteCommand cmd
} // foreach (SiteMapping sm in siteMaps)
conn.Close();
} // using (SQLiteConnection conn
} // try
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace); ExceptionLoggingService.Instance.WriteLog(String.Format("Exception in TestPlatypusDBUtils.SaveSiteMappingData: {0}", msgInnerExAndStackTrace));
} // catch
}
...但无法插入任何记录。日志文件包含 "Reached TestPlatypusDBUtils.SaveSiteMappingData"(达到 Insert 方法)但不包含 "Exception in TestPlatypusDBUtils.SaveSiteMappingData"。 ExecuteNonQuery() 是否不是插入的正确调用,或者有什么问题?
更新
我在第一个日志写入的下方添加了这个:
MessageBox.Show(String.Format("siteMappings about to be inserted into SiteMapping table: {0}", siteMappings));
...我看到了这个:
我不知道这是否意味着 SiteMappings 中实际上没有任何内容,或者我试图以错误的方式查看内容。我首先附加了一个“.ToString()”,但它是灰色的,所以认为它没有实际意义并且会静音。
更新 2
显然根本问题是没有 SiteMappings 被传递给该方法。我添加了这个:
foreach (SiteMapping sm in siteMaps)
{
MessageBox.Show(String.Format("this siteMap is {0}", sm));
...永远不会看到 "this siteMap is [bla]"。
为了将来参考,上面的尖叫声显示了 "empty" IEnumerable 中包含的内容。
更新 3
原来是数据问题(GIGO)。或者,试图进入的垃圾不会进入。
您 LocationNumber
提到了两次。
....
//SHOULD BE [ID], PROBABBLY
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.Id));
cmd.Parameters.Add(new SQLiteParameter("SiteNumber", sm.SiteNumber.ToString()));
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.LocationNumber));
cmd.Parameters.Add(new SQLiteParameter("SiteName", sm.SiteName));
....
我的猜测是在您决定站点映射是一种他们可以在 Windows CE 上存储信息而实际上不需要创建新文件的方式之前的人。
为什么 IEnumerable?传递一个列表怎么样?
那么,在您的服务器上,这些字段是什么样的?
我已经有 5 年多没有使用 SQLite 了,即便如此我也没有使用很长时间。
如果 SQLite 支持命名参数,你可以这样做(基于 Microsoft T-SQL):
private void IPlatypusDBUtils.SaveSiteMappingData(List<TSql> siteMappings) {
var isnull = (siteMapping == null) ? "True" : "False";
var count = (siteMapping == null) ? "-1" : siteMapping.Count.ToString();
ExceptionLoggingService.Instance.WriteLog(
String.Format("siteMapping is null? {0} siteMapping Count: {1}",
isnull, count));
string sqlCmd =
@"INSERT INTO SiteMapping " +
"(Id, SiteNumber, LocationNumber, SiteName) " +
"VALUES " +
"(@Id, @SiteNumber, @LocationNumber, @SiteName)";
using (var cmd = new SQLiteCommand(sqlCmd, new SQLiteConnection(PlatypusUtils.GetDBConnection()))) {
// Setup your parameters here,
// using the data types found in your database,
// before ever opening the database connection.
cmd.Parameters.Add("@Id", DbType.Int);
cmd.Parameters.Add("@SiteNumber", DbType.VarChar, 50); // or Platypusconsts.currentsitenum ?
cmd.Parameters.Add("@LocationNumber", DbType.Int);
cmd.Parameters.Add("@SiteName", DbType.VarChar, 50);
try { // now open your connection
cmd.Connection.Open();
foreach (var sm in siteMappings) {
cmd.Parameters["@Id"].Value = sm.Id;
cmd.Parameters["@SiteNumber"].Value = sm.SiteNumber.ToString();
cmd.Parameters["@LocationNumber"].Value = sm.LocationNumber;
cmd.Parameters["@SiteName"].Value = sm.SiteName;
cmd.ExecuteNonQuery();
}
} catch (SQLiteException ex) {
// Focus your Exception on the SQLiteException
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("Exception in TestPlatypusDBUtils.SaveSiteMappingData: {0}", msgInnerExAndStackTrace));
} finally {
// Placing your Close command here will work even if
// the code throws an exception.
cmd.Connection.Close();
}
}
}
因为我没有在任何地方安装 SQLite,所以无法为您测试。
不过,如果可行,您只需要创建一个命令并只打开一个数据库连接。
我有这段代码可以在 Windows CE / Compact Framework 应用程序的 SQLite 数据库中插入 1..N 条记录:
void IPlatypusDBUtils.SaveSiteMappingData(IEnumerable<SiteMapping> siteMappings)
{
ExceptionLoggingService.Instance.WriteLog("Reached TestPlatypusDBUtils.SaveSiteMappingData");
IEnumerable<SiteMapping> siteMaps = siteMappings;
try
{
using (SQLiteConnection conn = new SQLiteConnection(PlatypusUtils.GetDBConnection()))
{
conn.Open();
foreach (SiteMapping sm in siteMaps)
{
using (SQLiteCommand cmd = new SQLiteCommand(conn))
{
cmd.CommandText =
@"INSERT INTO SiteMapping (Id, SiteNumber, LocationNumber, SiteName) VALUES (@Id, @SiteNumber, @LocationNumber, @SiteName)";
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.Id));
cmd.Parameters.Add(new SQLiteParameter("SiteNumber", sm.SiteNumber.ToString())); // or Platypusconsts.currentsitenum ?
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.LocationNumber));
cmd.Parameters.Add(new SQLiteParameter("SiteName", sm.SiteName));
cmd.ExecuteNonQuery();
} // using (SQLiteCommand cmd
} // foreach (SiteMapping sm in siteMaps)
conn.Close();
} // using (SQLiteConnection conn
} // try
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace); ExceptionLoggingService.Instance.WriteLog(String.Format("Exception in TestPlatypusDBUtils.SaveSiteMappingData: {0}", msgInnerExAndStackTrace));
} // catch
}
...但无法插入任何记录。日志文件包含 "Reached TestPlatypusDBUtils.SaveSiteMappingData"(达到 Insert 方法)但不包含 "Exception in TestPlatypusDBUtils.SaveSiteMappingData"。 ExecuteNonQuery() 是否不是插入的正确调用,或者有什么问题?
更新
我在第一个日志写入的下方添加了这个:
MessageBox.Show(String.Format("siteMappings about to be inserted into SiteMapping table: {0}", siteMappings));
...我看到了这个:
我不知道这是否意味着 SiteMappings 中实际上没有任何内容,或者我试图以错误的方式查看内容。我首先附加了一个“.ToString()”,但它是灰色的,所以认为它没有实际意义并且会静音。
更新 2
显然根本问题是没有 SiteMappings 被传递给该方法。我添加了这个:
foreach (SiteMapping sm in siteMaps)
{
MessageBox.Show(String.Format("this siteMap is {0}", sm));
...永远不会看到 "this siteMap is [bla]"。
为了将来参考,上面的尖叫声显示了 "empty" IEnumerable 中包含的内容。
更新 3
原来是数据问题(GIGO)。或者,试图进入的垃圾不会进入。
您 LocationNumber
提到了两次。
....
//SHOULD BE [ID], PROBABBLY
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.Id));
cmd.Parameters.Add(new SQLiteParameter("SiteNumber", sm.SiteNumber.ToString()));
cmd.Parameters.Add(new SQLiteParameter("LocationNumber", sm.LocationNumber));
cmd.Parameters.Add(new SQLiteParameter("SiteName", sm.SiteName));
....
我的猜测是在您决定站点映射是一种他们可以在 Windows CE 上存储信息而实际上不需要创建新文件的方式之前的人。
为什么 IEnumerable?传递一个列表怎么样?
那么,在您的服务器上,这些字段是什么样的?
我已经有 5 年多没有使用 SQLite 了,即便如此我也没有使用很长时间。
如果 SQLite 支持命名参数,你可以这样做(基于 Microsoft T-SQL):
private void IPlatypusDBUtils.SaveSiteMappingData(List<TSql> siteMappings) {
var isnull = (siteMapping == null) ? "True" : "False";
var count = (siteMapping == null) ? "-1" : siteMapping.Count.ToString();
ExceptionLoggingService.Instance.WriteLog(
String.Format("siteMapping is null? {0} siteMapping Count: {1}",
isnull, count));
string sqlCmd =
@"INSERT INTO SiteMapping " +
"(Id, SiteNumber, LocationNumber, SiteName) " +
"VALUES " +
"(@Id, @SiteNumber, @LocationNumber, @SiteName)";
using (var cmd = new SQLiteCommand(sqlCmd, new SQLiteConnection(PlatypusUtils.GetDBConnection()))) {
// Setup your parameters here,
// using the data types found in your database,
// before ever opening the database connection.
cmd.Parameters.Add("@Id", DbType.Int);
cmd.Parameters.Add("@SiteNumber", DbType.VarChar, 50); // or Platypusconsts.currentsitenum ?
cmd.Parameters.Add("@LocationNumber", DbType.Int);
cmd.Parameters.Add("@SiteName", DbType.VarChar, 50);
try { // now open your connection
cmd.Connection.Open();
foreach (var sm in siteMappings) {
cmd.Parameters["@Id"].Value = sm.Id;
cmd.Parameters["@SiteNumber"].Value = sm.SiteNumber.ToString();
cmd.Parameters["@LocationNumber"].Value = sm.LocationNumber;
cmd.Parameters["@SiteName"].Value = sm.SiteName;
cmd.ExecuteNonQuery();
}
} catch (SQLiteException ex) {
// Focus your Exception on the SQLiteException
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("Exception in TestPlatypusDBUtils.SaveSiteMappingData: {0}", msgInnerExAndStackTrace));
} finally {
// Placing your Close command here will work even if
// the code throws an exception.
cmd.Connection.Close();
}
}
}
因为我没有在任何地方安装 SQLite,所以无法为您测试。
不过,如果可行,您只需要创建一个命令并只打开一个数据库连接。