c# - 无法在 Xamarin Android 项目中读取 SQLite 文件
问题描述
我有一个名为的文件Lego_Parts.db3
,它是一个已经填充了数据的 SQLite 文件。我在 Android Xamarin 项目的资产文件夹中有它。我必须设置数据库路径的代码是:
static PieceDB database;
public static PieceDB PieceDatabase
{
get
{
if (database == null)
{
database = new PieceDB(Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Lego_Parts.db3"));
}
return database;
}
}
当我尝试显示数据库中的数据(在 DatabaseTest.xaml 中)时,没有数据显示
这是任何适用的代码:
片断.cs
using SQLite;
namespace TestApp1
{
public class Piece
{
public int PartNum { get; set; }
public string PartName { get; set; }
public string Category { get; set; }
public string Url { get; set; }
}
}
PieceDB.cs
using SQLite;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace TestApp1
{
public class PieceDB
{
readonly SQLiteAsyncConnection _database;
public PieceDB(string dbPath)
{
_database = new SQLiteAsyncConnection(dbPath);
_database.CreateTableAsync<Piece>().Wait();
}
public Task<List<Piece>> GetAllPieces()
{
return _database.Table<Piece>().ToListAsync();
}
public Task<Piece> GetPiece(int partNum)
{
return _database.Table<Piece>().Where(i => i.PartNum == partNum).FirstOrDefaultAsync();
}
public Task<int> SavePieceAsync(Piece temp)
{
return _database.InsertAsync(temp);
}
}
}
数据库测试.xaml.cs
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TestApp1
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DatabaseTest : ContentPage
{
protected override async void OnAppearing()
{
base.OnAppearing();
listView.ItemsSource = await App.PieceDatabase.GetAllPieces();
}
public DatabaseTest()
{
InitializeComponent();
}
async void Handle_ItemTapped(object sender, ItemTappedEventArgs e)
{
if (e.Item == null)
return;
await DisplayAlert("Item Tapped", "An item was tapped.", "OK");
//Deselect Item
((ListView)sender).SelectedItem = null;
}
}
}
数据库测试.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="TestApp1.DatabaseTest">
<StackLayout Margin="20,35,20,20">
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding PartNum}"
Detail="{Binding Url}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
解决方案
您必须将数据库复制到文件位置。
首先,我建议将您的 db3 文件放在 Resources/Raw 文件夹中,因为它会使复制稍微容易一些。此外,Android 资源只能使用小写字母、数字和下划线,并且必须以字母开头,因此将您的 db 文件名更改为 lego_parts.db3 以供初学者使用。
然后在 MainActivity 的 OnCreate 中,执行以下操作:
var dbPath = Path.Combine (System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal), "lego_parts.db3"); // FILE NAME TO USE WHEN COPIED
var s = Resources.OpenRawResource(Resource.Raw.lego_parts); // DATA FILE RESOURCE ID
if (!System.IO.File.Exists(dbPath)) {
FileStream writeStream = new FileStream(dbPath, FileMode.OpenOrCreate, FileAccess.Write);
ReadWriteStream(s, writeStream);
}
并将以下方法添加到 MainActivity 类:
private void ReadWriteStream(Stream readStream, Stream writeStream)
{
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer, 0, Length);
// write the required bytes
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = readStream.Read(buffer, 0, Length);
}
readStream.Close();
writeStream.Close();
}
然后,您可以使用 dbPath 作为文件路径连接到您的数据库。
在 iOS 上,您可以将 lego_parts.db3 放在 iOS 项目的根文件夹中,然后在 AppDelegate.FinishedLaunching 方法中使用以下代码复制它:
var dbPath = Path.Combine (System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal), "lego_parts.db3");
var appDir = NSBundle.MainBundle.ResourcePath;
var seedFile = Path.Combine(appDir, "lego_parts.db3");
if (!File.Exists(dbPath) && File.Exists(seedFile))
File.Copy(seedFile, dbPath);
推荐阅读
- maven - Maven 声纳插件问题
- c - 如何在可执行文件后立即设置 CMAKE_STATIC_LINKER_FLAGS?[tcc -ar]
- deque - 枚举双端队列的问题
() - php - Symfony 序列化程序的性能问题
- javascript - 每次刷新后只显示一次通知
- mysql - AWS Lambda 函数从数据库查询返回错误值
- java - HTTP 状态 404 - 未找到 - 在 nginx 容器中部署 java 应用程序时出错
- javascript - 根据另一个对象的键值获取键值
- azure - 使用 Kusto Query 在 Azure LAWS 中创建计算机组
- python - 重新启动 Firefox 并恢复上一个会话 - Python