我有一个名为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中)时,没有数据显示
以下是任何适用的代码:
Piece.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);
}
}
}
DatabaseTest.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;
}
}
}
DatabaseTest.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>
答案 0 :(得分:1)
您将必须将数据库复制到文件位置。
首先,我建议将db3文件放在Resources / Raw文件夹中,因为这会使复制稍微容易一些。另外,Android资源应仅使用小写字母,数字和下划线,并且必须以字母开头,因此对于初学者来说,请将您的数据库文件名更改为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);
答案 1 :(得分:0)
通过在android项目中创建此类,我能够从android资产文件夹中复制数据库文件:
CreateConnection.cs
namespace TestApp1.Droid
{
public class CreateConnection
{
public void Open()
{
var sqliteFilename = "lego_parts.db3";
string documentsDirectoryPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsDirectoryPath, sqliteFilename);
if(!File.Exists(path))
{
using (var binaryReader = new BinaryReader(Android.App.Application.Context.Assets.Open(sqliteFilename)))
{
using (var binaryWriter = new BinaryWriter(new FileStream(path, FileMode.Create)))
{
byte[] buffer = new byte[2048];
int length = 0;
while((length = binaryReader.Read(buffer, 0, buffer.Length)) > 0)
{
binaryWriter.Write(buffer, 0, length);
}
}
}
} else
{
Console.WriteLine("Database already saved on device");
}
}
}
}
并从Android项目的OnCreate()方法调用Open()方法
MainActivity.cs
protected override async void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
await CrossMedia.Current.Initialize();
CrossCurrentActivity.Current.Init(this, savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
CreateConnection connection = new CreateConnection();
connection.Open();
LoadApplication(new App());
}