我收到此错误消息:
“Microsoft.Data.Sqlite.SqliteConnection”的类型初始值设定项引发异常。
更明确地说,我得到:
Message =“Microsoft.Data.Sqlite.SqliteConnection”的类型初始值设定项引发异常。
内部异常 = System.Exception:您需要调用 SQLitePCL.raw.SetProvider()。如果您使用的是捆绑包,则可以通过调用 SQLitePCL.Batteries.Init() 来完成。在 SQLitePCL.raw.get_Provider() 在 SQLitePCL.raw.sqlite3_win32_set_directory(Int32typ,字符串路径) 在 Microsoft.Data.Sqlite.Utilities.BundleInitializer.Initialize() 在 Microsoft.Data.Sqlite.SqliteConnection..cctor()
堆栈跟踪 = 位于 Microsoft.Data.Sqlite.SqliteConnection..ctor(String connectionString) 位于 CartographerYou.MainPage.InsertMapRecord(String mapName, String mapNotes, Int32 PreferredZoomLevel) 位于 CartographerYou.MainPage.btnCre8NewMap_Click(Object sender, RoutedEventArgs e)
这是 StackTrace 中提到的两个方法(事件处理程序和自定义方法):
private async void btnCre8NewMap_Click(object sender, RoutedEventArgs e)
{
try
{
string mapName = string.Empty;
string mapNotes = string.Empty;
int defaultZoomLevel = 1;
ClearLocations();
// Popul8 the cmbx
for (int i = 1; i < 20; i++)
{
cmbxCre8MapZoomLevels.Items.Add(i.ToString());
}
ContentDialogResult result = await cntDlgCre8Map.ShowAsync();
if (result == ContentDialogResult.Primary)
{
mapName = txtbxMapName.Text;
mapNotes = txtbxMapNotes.Text;
defaultZoomLevel = cmbxCre8MapZoomLevels.SelectedIndex + 1;
// select "Step Into Specific" from context menu
await InsertMapRecord(mapName, mapNotes, defaultZoomLevel);
}
// else do nothing (don't save)
}
catch (Exception ex)
{
string excMsg = string.Format("{0} Inner Exception: {1} Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
MessageDialog exceptionMsgDlg = new MessageDialog(excMsg, "btnCre8NewMap_Click");
await exceptionMsgDlg.ShowAsync();
}
}
private async Task InsertMapRecord(string mapName, string mapNotes, int preferredZoomLevel)
{
path = folder.Path;
connStr = string.Format(connStrBase, path);
try
{
using (SqliteConnection conn = new SqliteConnection(connStr))
{
String query = "INSERT INTO dbo.CartographerMain " +
"(MapName, MapNotes, PreferredZoomLevel) " +
"VALUES (@MapName, @MapNotes, @PreferredZoomLevel)";
using (SqliteCommand cmd = new SqliteCommand(query, conn))
{
cmd.Parameters.AddWithValue("@MapName", mapName);
cmd.Parameters.AddWithValue("@MapNotes", mapNotes);
cmd.Parameters.AddWithValue("@PreferredZoomLevel", preferredZoomLevel);
await conn.OpenAsync();
int result = await cmd.ExecuteNonQueryAsync();
if (result < 0)
{
MessageDialog dialog = new MessageDialog("Error inserting data into CartographerMain");
await dialog.ShowAsync();
}
}
}
}
catch (SqliteException sqlex)
{
string sqlExcMsg = string.Format("{0} Inner Exception: {1} Stack Trace: {2}", sqlex.Message, sqlex.InnerException, sqlex.StackTrace);
MessageDialog dialog = new MessageDialog(sqlExcMsg, "InsertMapRecord");
await dialog.ShowAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
基于需要调用 SQLitePCL.raw.SetProvider() 的内部异常,我更改了代码:
using (SqliteConnection conn = new SqliteConnection(connStr))
{
. . .
Run Code Online (Sandbox Code Playgroud)
...对此:
SqliteConnection conn = new SqliteConnection(connStr);
SQLitePCL.raw.SetProvider();
. . .
Run Code Online (Sandbox Code Playgroud)
...但我不知道我需要将什么传递给 SetProvider() - 如果这真的是问题的真正解决方案。
这就是我通过该代码得到的结果:
需要将什么传递给 SetProvider()?
我认为不鼓励SQLitePCL.raw
直接使用:
……那不是你想做的事。这不是您用来编写应用程序的那种 SQLite 库。它是围绕 SQLite C API 的一个非常薄的 C# 包装器。这是“生的”。
假设您对此感到满意,您可以考虑使用包装器,例如sqlite-net(作者在其页面上提到它是选项之一):
class CartographerMain // the library provides ORM functionality, so i created a simple object based on your example
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string MapName { get; set; }
public string MapNotes { get; set; }
public int PreferredZoomLevel { get; set; }
}
private async Task InsertMapRecord(string mapName, string mapNotes, int preferredZoomLevel)
{
var path = "a.db";
var connStr = string.Format(connStrBase, path);
SQLiteAsyncConnection db = null;
try
{
db = new SQLiteAsyncConnection(connStr);
await db.CreateTableAsync<CartographerMain>();
var result = await db.InsertAsync(new CartographerMain { MapName = mapName, MapNotes = mapNotes, PreferredZoomLevel = preferredZoomLevel });
if (result < 0)
{
MessageDialog dialog = new MessageDialog("Error inserting data into CartographerMain");
await dialog.ShowAsync();
}
}
catch (SQLiteException sqlex)
{
string sqlExcMsg = string.Format("{0} Inner Exception: {1} Stack Trace: {2}", sqlex.Message, sqlex.InnerException, sqlex.StackTrace);
MessageDialog dialog = new MessageDialog(sqlExcMsg, "InsertMapRecord");
await dialog.ShowAsync();
}
finally
{
await db.CloseAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
为了使上面的代码正常工作,我只引用了一个nuget 包- 它取决于SQLitePCLRaw.bundle_green
,我认为这是您无论如何都会安装的包
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="sqlite-net-pcl" Version="1.7.335" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
UPD
假设您在使用Microsoft.Data.Sqlite时遇到此异常,我怀疑该问题可能源于SQLitePCLRaw.bundle_e_sqlite3
(底层依赖项)未针对运行它的环境捆绑本机二进制文件。
如果您已Microsoft.Data.Sqlite
安装,则应该将e_sqlite3
捆绑包作为依赖项提供,并且可以尝试使用dynamic
提供程序
SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_dynamic_cdecl())
Run Code Online (Sandbox Code Playgroud)
如果这不起作用,您可以搜索SQLitePCLRaw.provider.e_sqlite3.*
您的特定目标并尝试如下操作:
SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6825 次 |
最近记录: |