[英]SQLite.Net Won't Create In Win IoT Library
I have been struggling to find a way of persisting an SQLite database on a Pi under Win IoT which can be accessed by different background applications (not concurrently). 我一直在努力寻找一种在Win IoT下将Pi上保留SQLite数据库的方法,该方法可以由不同的后台应用程序访问(不能同时访问)。
I thought I had the answer when I discovered Libraries (Music, Pictures, Videos - but perversely not Documents, without more work). 当我发现图书馆(音乐,图片,视频-但反而没有文档,而又没有更多工作)时,我以为我找到了答案。 I can create a text file in one app and write it to the Pictures library's default folder.
我可以在一个应用程序中创建一个文本文件,并将其写入图片库的默认文件夹。 I can then read the text file with another app.
然后,我可以使用另一个应用程序读取文本文件。 File.Exists returns true.
File.Exists返回true。 Bingo (I thought)!
宾果游戏(我认为)!
However, SQLite will not create a database in the folder or open an existing database that I copy to the folder. 但是,SQLite不会在该文件夹中创建数据库,也不会打开我复制到该文件夹中的现有数据库。 SQLite.Net.SQLiteConnection returns an SQLite exception: "Could not open database file: C:\\Data\\Users\\DefaultAccount\\Pictures\\MyDb.db (CannotOpen)" - no further clues.
SQLite.Net.SQLiteConnection返回一个SQLite异常:“无法打开数据库文件:C:\\ Data \\ Users \\ DefaultAccount \\ Pictures \\ MyDb.db(CannotOpen)”-没有其他线索。
The folder appears to grant full permissions. 该文件夹似乎授予了完全权限。 Does anyone have any ideas, please?
请问有人有什么想法吗?
Creating and Writing a text file: 创建和写入文本文件:
using System;
using Windows.ApplicationModel.Background;
using System.IO;
using System.Diagnostics;
//*** NOTE: Pictures Library checked in Package.appxmanifest 'Capabilities'
namespace LibraryTest
{
public sealed class StartupTask : IBackgroundTask
{
private BackgroundTaskDeferral Deferral;
public async void Run (IBackgroundTaskInstance taskInstance)
{
Deferral = taskInstance.GetDeferral ();
var myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync
(Windows.Storage.KnownLibraryId.Pictures);
string path = myPictures.SaveFolder.Path;
Debug.WriteLine ($"'Pictures' Folder: {path}");
string newFilePath = Path.Combine (path, "TestTextFile.txt");
Debug.WriteLine ($"New File Path: {newFilePath}");
try {
using ( var stream = File.OpenWrite (newFilePath) ) {
using ( var writer = new StreamWriter (stream) ) {
writer.Write ("This is some test text.");
}
}
Debug.WriteLine ($"File created OK");
}
catch (Exception ex) { Debug.WriteLine ($"Exception: {ex.Message}"); }
}
}
}
Produced: 产生:
'Pictures' Folder: C:\Data\Users\DefaultAccount\Pictures
New File Path: C:\Data\Users\DefaultAccount\Pictures\TestTextFile.txt
File created OK
Reading: 读:
using System;
using Windows.ApplicationModel.Background;
using System.IO;
using System.Diagnostics;
//*** NOTE: Pictures Library checked in Package.appxmanifest 'Capabilities'
namespace ReadLibraryTest
{
public sealed class StartupTask : IBackgroundTask
{
private BackgroundTaskDeferral Deferral;
public async void Run (IBackgroundTaskInstance taskInstance)
{
Deferral = taskInstance.GetDeferral ();
var myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync
(Windows.Storage.KnownLibraryId.Pictures);
string path = myPictures.SaveFolder.Path;
Debug.WriteLine ($"'Pictures' Folder: {path}");
string newFilePath = Path.Combine (path, "TestTextFile.txt");
Debug.WriteLine ($"New File Path: {newFilePath}");
try {
using ( var stream = File.OpenRead (newFilePath) ) {
using ( var reader = new StreamReader (stream) ) {
string fileContents = reader.ReadLine ();
Debug.WriteLine ($"First line of file: '{fileContents}'");
}
}
Debug.WriteLine ($"File read OK");
}
catch ( Exception ex ) { Debug.WriteLine ($"Exception: {ex.Message}"); }
}
}
}
Produced: 产生:
'Pictures' Folder: C:\Data\Users\DefaultAccount\Pictures
New File Path: C:\Data\Users\DefaultAccount\Pictures\TestTextFile.txt
First line of file: 'This is some test text.'
File read OK
However, SQLite will not create a database in the folder or open an existing database that I copy to the folder.
但是,SQLite不会在该文件夹中创建数据库,也不会打开我复制到该文件夹中的现有数据库。 SQLite.Net.SQLiteConnection returns an SQLite exception: "Could not open database file: C:\\Data\\Users\\DefaultAccount\\Pictures\\MyDb.db (CannotOpen)" - no further clues.
SQLite.Net.SQLiteConnection返回一个SQLite异常:“无法打开数据库文件:C:\\ Data \\ Users \\ DefaultAccount \\ Pictures \\ MyDb.db(CannotOpen)”-没有其他线索。
Yes, I reproduced this issue. 是的,我转载了这个问题。 It seems this folder does not work with SQLite file operations but I don't know where the problem is.
看来此文件夹不适用于SQLite文件操作,但我不知道问题出在哪里。
As a workaround, you can use PublisherCacheFolder . 解决方法是,可以使用PublisherCacheFolder 。 I create the .db file and write data in one background app.
我创建.db文件并在一个后台应用程序中写入数据。 And read the data from another background app.
并从另一个后台应用程序读取数据。 It works.
有用。
Contact class: 联系人类别:
public sealed class Contact
{
public int Id { get; set; }
public string Name { get; set; }
}
Create and write file: 创建和写入文件:
StorageFolder sharedFonts = Windows.Storage.ApplicationData.Current.GetPublisherCacheFolder("test");
var sqlpath = System.IO.Path.Combine(sharedFonts.Path, "MyDb.db");
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), sqlpath))
{
conn.CreateTable<Contact>();
for (var i = 0; i < 100; i++)
{
Contact contact = new Contact()
{
Id = i,
Name = "A"
};
conn.Insert(contact);
}
}
Read file: 读取文件:
StorageFolder sharedFonts = Windows.Storage.ApplicationData.Current.GetPublisherCacheFolder("test");
var sqlpath = System.IO.Path.Combine(sharedFonts.Path, "MyDb.db");
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), sqlpath))
{
var query = conn.Table<Contact>().Where(v => v.Name.Equals("A"));
foreach (var stock in query)
Debug.WriteLine("contact: " + stock.Id);
}
To use this publisher folder you need add the following lines in Package.appxmanifest: 要使用此发布者文件夹,您需要在Package.appxmanifest中添加以下行:
<Extensions>
<Extension Category="windows.publisherCacheFolders">
<PublisherCacheFolders>
<Folder Name="test" />
</PublisherCacheFolders>
</Extension>
</Extensions>
Thanks, Rita. 谢谢,丽塔。 Worked very well.
工作得很好。 For the benefit of anyone reading, I am using the async version of SqlLite and create the connection as follows:
为了使任何人受益,我正在使用SqlLite的异步版本并按如下方式创建连接:
const string FileName = "MyFile.db";
string DbDir;
string DbPath;
Constructor:
DbDir = Windows.Storage.ApplicationData.Current.GetPublisherCacheFolder("test").Path;
DbPath = Path.Combine (DbDir, DbFileName);
public SQLite.Net.Async.SQLiteAsyncConnection GetConnectionAsync ()
{
var connectionFactory = new Func<SQLite.Net.SQLiteConnectionWithLock>(()=>
new SQLite.Net.SQLiteConnectionWithLock(new SQLitePlatformWinRT(),
new SQLite.Net.SQLiteConnectionString(DbPath, storeDateTimeAsTicks: false)));
var asyncConnection = new SQLiteAsyncConnection(connectionFactory);
return asyncConnection;
}
Then, for instance, read a table of type Parms: 然后,例如,读取一个Parms类型的表:
public async Task<Parms> ReadParmsAsync ()
{
var db = GetConnectionAsync ();
var query = db.Table<Parms> ().Where (p => p.Id == 1);
return await query.FirstOrDefaultAsync ();
}
My concern about the SQLite async connection is that it is not IDisposable. 我对SQLite异步连接的担心是它不是IDisposable。 Therefore, will the 'factory' eventually run out of steam (memory, handles)?
因此,“工厂”最终会耗尽精力(内存,句柄)吗? But I guess that is a subject for another thread.
但是我想这是另一个线程的主题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.