#sqlite #uwp #sqlite-net-pcl
Вопрос:
Я разрабатываю приложение UWP, которое может одновременно загружать файлы и записывать данные файлов в базу данных SQLite. Я использовал sqlite-net-pcl в качестве оболочки SQLite. Я получаю исключения из БД, когда выполняю несколько транзакций базы данных. Это пример кода, как я использую SQLite.
AppSQLite.cs
//Database name
public static readonly string DATABASE_NAME = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "App.db");
SQLiteAsyncConnection conn = null;
/// <summary>
/// Constructor
/// </summary>
public SASQLite()
{
try
{
conn = new SQLiteAsyncConnection(DATABASE_NAME);
CreateTables();
}
catch (Exception er)
{
Log(er);
}
}
public async Task CreateTables()
{
try
{
await CreateUserTable();
await CreateUserProject();
await CreateUserFacility();
await CreateTopic();
//More tables to create
}
catch (Exception er)
{
Log(er);
}
finally
{
await conn.CloseAsync();
}
AppUtils.PrintDebug("=========End", CLASS_NAME, "CreateTables");
}
// All the table creations similar to this
private async Task CreateUserTable()
{
if (conn != null)
{
await conn.CreateTableAsync<User>();
}
else
{
//null connection
}
}
Тема: <url>
/// <summary>
/// add topic to topic table
/// </summary>
/// <param name="topicModel"></param>
/// <returns></returns>
public static async Task AddTopic(TopicModel topicModel)
{
try
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection(AppSQLite.DATABASE_NAME);
// create a new Id for the db entry
string id = Guid.NewGuid().ToString();
Topic topic = new Topic()
{
Id = id,
TopicId = topicModel.Id,
TopicTitle = topicModel.TopicTitle,
TopicContent = topicModel.Content,
DocumentId = topicModel.DocumentId
};
await conn.InsertAsync(topic);
await conn.CloseAsync();
}
catch (Exception er)
{
Log(ex);
}
}
}
Write data to database
......
foreach (IXmlNode topicElement in TopicElementList)
{
if (topicElement.NodeType == NodeType.ElementNode)
{
string itemType = null;
if (topicElement.Attributes.GetNamedItem("itemType") != null)
{
itemType = topicElement.Attributes.GetNamedItem("itemType").NodeValue as string;
}
if (itemType == "Topic")
{
// Create topic using topicElement
............
await TopicDAL.AddTopic(topic);
}
................................
}
}
There can be 1000 topics for each download and user can do 100 of such downloads. So this fails with different DB exceptions as followings.
TopicDAL::AddTopic::=========Start TopicDAL::AddTopic::=========Id : d94a0a04-4bea-4b68-8757-cb304e36d16b Exception thrown: ‘System.NullReferenceException’ in System.Private.CoreLib.dll TopicDAL::AddTopic::=========Exception : System.NullReferenceException: Object reference not set to an instance of an object. at SQLite.PreparedSqlLiteInsertCommand.ExecuteNonQuery(Object[] source) at SQLite.SQLiteConnection.Insert(Object obj, String extra, Type objType) at SQLite.SQLiteAsyncConnection.<>c_DisplayClass33_0
1.<WriteAsync>b_0() at System.Threading.Tasks.Task
1.InnerInvoke() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) — End of stack trace from previous location where exception was thrown — at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Taskamp; currentTaskSlot) — End of stack trace from previous location where exception was thrown — at App.Repository.DAL.TopicDAL.AddTopic(TopicModel topicModel)===== = ===Исключение : Система.Исключение ArgumentNullException: SafeHandle не может быть нулевым. Имя параметра: pHandle в системе.СтабХелперы.СтабХелперы.SafeHandleAddRef(функция SafeHandle, логическое значение и успех) в SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_prepare_v2(база данных sqlite3, байт* pSql, 32 байта, IntPtr и stmt, Байт* и ptrRemain) в SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_prepare_v2(база данных sqlite3, sql utf8z, IntPtr и stm, utf8z и хвост) в SQLitePCL.raw.sqlite3_prepare_v2(база данных sqlite3, sql utf8z, sqlite3_stmt и stmt) в SQLite.SQLite3.Подготовьте 2(бд sqlite3, строковый запрос) в SQLite.Подготовитьклитейинсерт-команду.ExecuteNonQuery(объект[] источник) в SQLite.Подключение к SQLiteConnection.Вставьте(Объект obj, Дополнительная строка, Тип objType) в SQLite.Соединение SQLiteAsyncConnection.<>c_DisplayClass33_0<>
1.<WriteAsync>b_0() at System.Threading.Tasks.Task
1.InnerInvoke() в системе.Нарезание резьбы.Контекст исполнения.RunInternal(ExecutionContext ExecutionContext, обратный вызов ContextCallback, состояние объекта) — Конец трассировки стека из предыдущего местоположения, в котором в системе было вызвано исключение.Нарезание резьбы.Задачи.Задачи.ExecuteWithThreadLocal(Taskamp; currentTaskSlot) — Конец трассировки стека из предыдущего местоположения, где было создано исключение —
Не могли бы вы, пожалуйста, направить меня, если есть какие-либо проблемы с этим дополнением? Если это связано с оболочкой SQLite, что может быть лучшим вариантом для использования в этом сценарии?
Комментарии:
1. Поскольку ваши вставленные данные получены из Интернета, воспроизвести вашу проблему сложно. Сообщение об исключении запрашивает пустую ссылку в
AddTopic
методе, поэтому вам необходимо проверить, пуст ли переданный объект (topicModel
), прежде чем вставлять его в таблицу. Кроме того, вам также необходимо проверить, открыто ли соединение с базой данных.