Unable to open SQLite database file from local data store of UWP app - sqlite

I'm using this section of this official MSDN tutorial: Use a SQLite database in a UWP app but I'm getting the following error:
REMARK: There are many online posts related (or similar) to this issue but none seems to have a solution. Most of these posts are a few years old so I thought this issue would have been resolved by now. Moreover, the above mentioned tutorial is using .NET Standard Class library project, as well. And the online posts regarding the issue do not have .NET Standard involved. So, I was wondering if the issue is caused by the use of .NET Standard library. Regardless, a solution will be greatly appreciated.
SQLite Error 14: 'unable to open database file'
Error occurs at line db.Open() of this code:
public static void InitializeDatabase()
{
using (SqliteConnection db =
new SqliteConnection("Filename=sqliteSample.db"))
{
db.Open();
String tableCommand = "CREATE TABLE IF NOT " +
"EXISTS MyTable (Primary_Key INTEGER PRIMARY KEY, " +
"Text_Entry NVARCHAR(2048) NULL)";
SqliteCommand createTable = new SqliteCommand(tableCommand, db);
createTable.ExecuteReader();
}
}
NOTES:
The line just below the above code reads: This code creates the SQLite database and stores it in the application's local data store. That means the app should have access to that local data store.
I'm using latest version 16.3.5 of VS2019 on Windows 10. The target version on the project is selected as Windows 10 1903 and min version as Windows 10 1903
UPDATE
This similar official 3 years old sample works fine. So, the problem seems to be related to newer versions of .NET Core. But I need to use latest version of .NET Core for other features my app is using that are not available in the older versions.
I also tried this similar old tutorial, but it did not on new version of .NET Core work either - giving exact same error.
The old problem reported in 2016 here to Microsoft seems to have resurfaced again with the new version of .NET Core.

This is a misunderstanding, SqliteConnection db = new SqliteConnection("Filename=sqliteSample.db") can not create a Sqlite file, but access the existing Sqlite database file through the path.
So you need to create a valid sqliteSample.db file and place it in the root directory of the UWP project. Select the content in the Properties -> Build operation to ensure it will be loaded into the application directory.
Update
Please create the sqliteSample.db file in LocalFolder first.
await ApplicationData.Current.LocalFolder.CreateFileAsync("sqliteSample.db", CreationCollisionOption.OpenIfExists);
Then use the path to access the database file
string path = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqliteSample.db");
using (SqliteConnection db =
new SqliteConnection($"Filename={path}"))
{
// ...
}
Best regards.

Related

SQLite no longer seems to work on xamarin android

We have a Xamarin.Forms project that needed to use the sqlite local db to store date. EF Core's sqlite library was used to set this up and by different developers from different PCs (vs 2019). Initially, it was used with the Database.EnsureCreated() function and later with ef core's migrations. All went smooth for more than a month.
Last week all of a sudden the android app wouldn't start on any one's PC due to some error with sqlite. It showed the following error:
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
I spent a while trying all kinds of fixes and rollbacks thinking it was an issue with the code. This included the following:
Deleted obj and bin folders, cleaned and rebuilt for all below steps.
Downgraded the version of ef to 2.2.3 (the version we started with)
Rolled back to git commits up to a week back
Upgraded the versions of dependencies of ef core
Removed the past few migrations
Downgraded xamarin forms to 3.6.x
After trying the above and several other fixes, finally upgrading the versions of java and android SDK worked last Friday (on all PCs). Once this fix worked everything went smooth that day. On Tuesday once again the issue was back (no library updates or code changes). A deeper look at EF Cores logging shows that it crashes the moment it attempts to connect to a db.
The issue can be replicated on the android devices but not the emulators. I am not sure if there is some new permission in android we need to request for.
I finally created a new xamarin forms project with sqlite setup. I used the pcl library and ef core. I still found the same error.
Here is the git hub that replicates the issue https://github.com/neville-nazerane/xamarin-site
Update
Just something i noticed. eariler my database file was named "main.db". Now no matter what i change this file name to or no matter what variables i change. it always shows database name as "main" in logs. Not sure if changing the db name would fix the issue. However, never found a way to change this db name. I tried different connection strings, it just said "database" and "db" were unknown keys
Update
Steps to replicate:
using (var db = new AppDbContext())
{
db.Add(new Person {
Age = 55,
Name = "Neville"
});
db.SaveChanges();
Person[] alldata = db.People.ToArray();
}
The definitions of Person and AppDbContext are quite obvious. So, with the spirit of not making the question too long, I am not posting it here. However, if required I can post them too.
This is a bug with the Xamarin.Forms and Mono.
It was detected since a couple of months ago, it was fixed but then there was some regression (with VS 2019 v16.1).
Even with the latest release (v16.1.2) the bug still happens, so we need to wait for a fix.
Sources:
https://github.com/mono/mono/issues/14170
https://github.com/xamarin/xamarin-android/issues/3112
https://github.com/xamarin/xamarin-android/issues/2920
Due to slight differences of the particular file systems on the native side, I would suggest creating an interface to handle the actual database file handling on the native application level.
So here is how I implemented SQLite using the nuget package SQLite.Net-PCL:
In the shared project, create a new interface, for instance FileHandler.cs
public interface IFileHandler
{
SQLite.SQLiteConnection GetDbConnection();
}
You may want to extend that with more methods to save or retrieve various files, but for now we will just have the GetDbConnection Method to retrieve a working SQLite Connection.
Now in your Android implementation, we add the native implementation to that interface:
Create a new class called FileHandler.cs in your android project:
[assembly: Dependency(typeof(FileHandler))]
namespace YourProjectName.Droid
{
public class FileHandler : IFileHandler
{
public SQLite.SQLiteConnection GetDbConnection()
{
string sqliteFilename = "YourDbName.db3";
string path = Path.Combine(GetPersonalPath(), sqliteFilename);
SQLiteConnectionString connStr = new SQLiteConnectionString(path, true);
SQLiteConnectionWithLock connection = new SQLiteConnectionWithLock(connStr, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.NoMutex);
return connection;
}
private string GetPersonalPath()
{
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
}
}
Now back again in your shared code you can access that connection with the following code:
using (SQLiteConnection connection = DependencyService.Get<IFileHandler>().GetDbConnection())
{
// Do whatever you want to do with the database connection
}
Alright mate, I don't understand what issue you are facing. It might be an issue with your machine, I'd suggest using another computer/laptop.
I took the exact code that you shared on the Github. I was able to build it on my Mac computer in VS 2019 and installed the application in debug mode on my phone. I was able to add a date successfully, as you can see in the picture, and I placed an Exception Catchpoint and faced no exceptions.
I then proceeded to add another entry with the same details and it errored out with the message that you can see here
I would also suggest using Xamarin Profiler or any other Android logger to see the Stack Trace that you aren't able to see in your application output. It will give you details of the error, that you can share here for us to understand better.

MvvmCross SQLite plugin in Windows Phone 8

I'm creating a cross-platform application (Android, iOS, WP8) which using multiple SQLite databases. I installed MvvmCross.HotTuna.Plugin.Sqlite on all platforms, but it is not working on WP8. I'm getting this exception:
"Could not open database file: C:\\Data\\Users\\DefApps\\AppData\\{284E2D10-051E-48D8-B895 E8126CCE3192}\\Local\\database.sqlite (CannotOpen)".
I'm opening the database like this:
dataService.Initialize(Path.Combine(ApplicationData.Current.LocalFolder.Path, filename));
Then I tried to swith to the new Sqlite plugin (MvvmCross - Community SQLite-Net Plugin), and it giving me strange errors on almost every query:
Message: "not an error"
StackTrace: " at Community.SQLite.SQLite3.Prepare2(sqlite3 db, String query)\r\n at Community.SQLite.SQLiteCommand.Prepare()\r\n at Community.SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__0`1.MoveNext()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at Community.SQLite.SQLiteCommand.ExecuteQuery[T]()\r\n at Community.SQLite.SQLiteConnection.Query[T](String query, Object[] args)\r\n at
Any suggestions how can I make it work?
EDIT:
I found out that the reason behind "not an error" was my multi-threading. I used Task.Run and await to create background thread (which worked fine on iOS and Android, but it failed on WP8). I removed that from my code (with #if WINDOWS_PHONE directives) so right now it's working synchronously. But the Community SQLite plugin can't map my SQLite Date type to DateTime. It always gives me the same DateTime: {0001.01.01. 0:00:00}.
Btw how can I use native SQLite? Can you show me a sample? I need to add new SQLite lib to my WP8 project, and implement IDataService, ISQLiteConnectionFactory, and register them on:
Setup.InitializeLastChance()
{
Mvx.LazyConstructAndRegisterSingleton<IDataService, MyOwnDataService>();
Mvx.LazyConstructAndRegisterSingleton<ISQLiteConnectionFactory , MyOwnConnectionFactory>();
}

Insert a new GUID to Visual Studio 2013

How to create GUIDs in Visual Studio 2013? I had an add in that worked well in VS2012 but it does not work in VS2013. I found this Create GUID in VS2012 and this How to convert VS2012 add ins to VS2013 Packages but could not make it work (add ins are not my forte - I simply edit SQL scripts). Is there an easy way to get back this functionality?
If you're using ReSharper (highly recommended), you can create new GUIDs everywhere by typing nguid and pressing Tab.
Actually, uou can just use guidgen.exe which should get installed with VS.
Using menu TOOLS -> External Tools... add:
%Installation Path%\Microsoft Visual Studio 12.0\Common7\Tools\guidgen.exe
e.g.
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\guidgen.exe
Give the title of ‘Create GUID’ and it is there just as it was in VS2010.
The best tool / add-in for this is:
http://visualstudiogallery.msdn.microsoft.com/22795583-5cc9-4681-af8e-6084f3441655
I was also wondering how I should do this. I saw the following example: Inserting a Guid for VS 2012. For VS2013 you have to install the SDK. Once you have done that you will see the template project items for packages and also for addins when you go to add a new project.
Despite the documentation saying that addins were deprecated in VS2013 they do appear to work (I am using VS2013 Ulitmate v 12.0.21005.1 REL). You can follow the instructions in the previous article.
I also created a package which was relatively straight forward too. Using How to: Convert an Addin to a VS Package I was able to create the package.
As in the article I added the following using statements:
using EnvDTE;
using EnvDTE80;
I then changed the MenuItemCallback method to the following:
private void MenuItemCallback(object sender, EventArgs e)
{
DTE2 dte = (DTE2)GetService(typeof(DTE));
if (dte.ActiveDocument != null)
{
TextSelection objSel = (EnvDTE.TextSelection)(dte.ActiveDocument.Selection);
objSel.Insert(Guid.NewGuid().ToString());
}
}
After building the project I went to the bin\Debug folder and started the vsix file (GuidPackage.vsix in my case). This installed the package for use in the IDE.
I now have a menu item to insert guids into my code and am able to create a shortcut key stroke for it in the usual way.
Just use PowerShell from VS Package Manage Console:
Switch to Package Manager Console (or you can open PowerShell cmd).
Execute [guid]::NewGuid().
Result:
Guid
----
61dabfd8-9151-46f5-8d92-72306044d844
I prefer to use this solution:
_TUCHAR *guidStr = 0x00;
GUID *pguid = 0x00;
pguid = new GUID;
CoCreateGuid(pguid);
// Convert the GUID to a string UuidToString(pguid, &guidStr);
delete pguid;
One other tool that I came by was this extension. Works pretty good
"Insert new GUID" (Shift+Alt+G): Inserts a new GUID at the current position.
"Insert last GUID" (Ctrl+Shift+Alt+G): Re-inserts the last new GUID at the current position.

Exception when using SQLite in WinRT app

I'm building a Windows 8 app, and now I want to use SQLite for this app. I installed SQLite for Windows Runtime through the Visual Studio 2013 extension manager, and I added sqlite-net to my project through NuGet.
I'm trying to create a database in my app.xaml.cs OnLaunched, but I get this exception when I run the project:
Unable to load DLL 'sqlite3': The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
This is very strange because there is no error during compiling. Anyway, I think it tries to tell me that I need to reference an additional DLL: sqlite3.dll, but that doesn't work. I have 6 different DLLs on my file system: both debug and release versions of ARM, x64 and x86. I tried adding the x86 release version to my project but that results in this exception:
A reference to 'C:\Users\Leon\Documents\Visual Studio
2013\Projects\Googalytics\packages\SQLite\x86\sqlite3.dll' could not
be added. Please make sure that the file is accessible, and that it is
a valid assembly or COM component.
It's very sad that the documentation for sqlite-net sucks, it's very outdated (examples don't even work anymore), it's very incomplete and there is no mention of manually adding a DLL either. So I have 2 questions:
How do I fix this particular issue?
Where do I find up to date documentation for sqlite-net?
Edit: the code I use to create the DB is:
private void InitializeDatabase()
{
var db = new SQLiteConnection("Googalytics");
db.CreateTable<Account>();
db.CreateTable<WebProperty>();
db.CreateTable<Profile>();
}
I call that method from here:
InitializeDatabase();
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
{
throw new Exception("Failed to create initial page");
}
}
// Ensure the current window is active
Window.Current.Activate();
edit2: some more info about my setup:
Visual Studio 2013 RC
Windows 8.1 RTM
SQLite for Windows Runtime 3.8.0.2
sqlite-net 1.0.7
Your project has its build mode currently set to Any CPU, what is the default. Because the SqLite assembly is not build as AnyCPU you need to set your build mode to X86 and add the X86 SqLite reference.
When deploying your app you also need to create 3 packages instead of 1 AnyCPU package.
Because your project is AnyCPU you get the error message when trying to add the x86, x86 is not valid for AnyCPU.
UPDATE
I tried to replicate your problem. I installed the SQLite for Windows Runtime for Visual Studio Ultimate 2012, after that I created a Windows Store Project, then added the SqLite reference after that I added sqlite-net and last I added your code for DB creation.
I modified the code a little bit (path & tables). But my code gives no error at all.
I did not need to reference the SqLite assemblies myself. Because by installing the extension into Visual Studio you get the reference in your extension list (still need to select it, just not add the dlls):
But still like I said in my first answer, you need to set your build mode to something else than 'Any CPU'
My example is on my skydrive (when testing set configuration to x86).
UPDATE 2
Db path:
var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
var db = new SQLite.SQLiteConnection(dbPath);

EF 4.1 exception "The provider did not return a ProviderManifestToken string"

I am trying to replicate an example found on MSDN. I am using ASP.NET and EF 4.1 (CTP?). I've used NuGet to install the EntityFramework package.
I am getting this error: The provider did not return a ProviderManifestToken string ...
and the database is never created.
Here is my connection string:
<add name="HospitalContext"
connectionString=
"data source=.\SQLExpress;initial catalog=NewTestDB;integrated security=True;"
providerName="System.Data.SqlClient"/>
Here is my code:
var pat = new Patient { Name = "Shane123132524356436435234" };
db.Patients.Add(pat);
var labResult = new LabResult { Result = "bad", Patient = pat };
int recordAffected = db.SaveChanges();
Here is my context:
public class HospitalContext : DbContext
{
static HospitalContext()
{
Database.SetInitializer(new HostpitalContextInitializer());
}
public DbSet<Patient> Patients { get; set; }
public DbSet<LabResult> LabResults { get; set; }
}
public class HostpitalContextInitializer :
DropCreateDatabaseIfModelChanges<HospitalContext>
{
protected override void Seed(HospitalContext context)
{
context.Patients.Add(new Patient { Name = "Fred Peters" });
context.Patients.Add(new Patient { Name = "John Smith" });
context.Patients.Add(new Patient { Name = "Karen Fredricks" });
}
}
This is a fully patched SQL 2008 system, with VS 2010 SP1.
I was getting this error and tried a few of the earlier suggestions. Then I checked the Inner Exception and noticed I was getting a simple SQL login failure for the user. Just something else to check.
This can happen sometimes when you place the connection string within the app.config of the wrong project in Visual Studio.
For example, I got this problem in EF 4.1 (the released version) project + WCF Data Service project and I noticed that I didn't have a connection string specified in the Data Services Project, where it was being used.
I had the same problem, and I add the below code just after the instance of my context (onload by exemple)
context.Database.Connection.ConnectionString = #"Data Source=.\SQLExpress;Initial Catalog=Test;Integrated Security=True";
I was having same error, and actually it was login failed for the specified server. I removed "Integrated Security" attribute from the config connection string and it worked.
I had a similar issue with the MvcMusicStore app. I changed a line in the Web.config from
"Instance=true" to "Instance=false". It sometimes works without this tweak but I don't know what causes the difference. Reading this
http://msdn.microsoft.com/en-us/library/ms254504.aspx didn't really help.
By some certain reason of permission, EF can not create database connection.
I had faced the same problem all of one day. Finally I had tried following solution and it worked:
a/ Open IIS (I'm using IIS 7)
b/ Open advanced settings of appool which web site was using (Ex: DefaultAppPool)
c/ Look at Process Model group, change Identity value to "Localsystem"
Hope it work with you.
I was just having the same problem...
the solution that worked for me was:
run the client network configuration tool (type cliconfg in Run)
and make sure TCP/IP is enabled..
I finally cracked it - after a slight wild goose chase thinking it was due to permissions.
Revelation: USE SQL PROFILER
(Note: I recently downgraded from EF6 to EF5)
Using SQL Profiler I quickly found the last SQL executed before the reported failure:
SELECT TOP (1)
[Project1].[C1] AS [C1],
[Project1].[MigrationId] AS [MigrationId],
[Project1].[Model] AS [Model]
FROM ( SELECT
[Extent1].[MigrationId] AS [MigrationId],
[Extent1].[Model] AS [Model],
1 AS [C1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[MigrationId] DESC
Well look at that - something to do with migrations. It's looking in __MigrationHistory table - which I hadn't even realized it had created (I had already wiped out Migrations in my CSPROJ) and cleared that out.
So I pull up the rows for that table and see that it is tied to a specific product version (v6).
I actually downgraded from EF6 (which I didn't intend to install in the first place) to EF5 (which is more compatible with scaffolding) and that when the problems began.
My guess is that the Model (<Binary data>) column is not backward compatible - hence the The provider did not return a ProviderManifest instance error since it was unable to decode it.
I didn't have anything to lose and just wiped out this table completely and ran Update-Database -Verbose and then was back up and running.
If you're in an advanced environment or already in production then wiping out this table may not be the solution, but this way allowed me to get right back to work.
In using Visual Studio 11 Beta with EF4.1 and ASP.NET MVC, I nearly pulled my hair out until I found
http://connect.microsoft.com/VisualStudio/feedback/details/740623/asp-net-mvc-4-default-connection-string-improperly-escaped
To fix my problem, I went into Application_Start and changed
Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
to
Database.DefaultConnectionFactory = new SqlConnectionFactory(#"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
This error is only present while the .edmx file is open and disappears as soon as the file is closed again.
This quote from CodePlex , this worked with me (visual studio 2013 /MVC 5)
One other thing to consider if you're using EF Code First is that it sometimes doesn't automatically create the backing database to your DbContext class. The solution is to add your own connection string - you can use the connection string that may be present to handle the user/registration database that backs the Simple Membership Provider, as a template.
Finally, you will need to add a default constructor for the DbContext class you created:
public ChaletDb():base("ChaletConnection")
{
}
Here, the name of the connection string as you entered in your web.config file is used to direct the DbContext to create the database.
Very occasionally, I've had to manually create the database (in SQL Server Management Studio) which prompted it to work.
I have multiple projects in a solution and added EF to each project in different times. On some machines it was working and on some it failed with aforementioned error. It took me a while to notice that some of my project's app.config had this:
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
This is ok if you use LocalDb (new "sql express" like), but completely wrong if you don't have that specific server installed and use a regular SQL.
Solution: Remove the above code.
This is because connection to SQL server failed.
Make sure the User Account under-which you are running the process have access to SQL Server.
If you have generated the DbContext from parent thread (like using dependency Injection) and then if you are impersonating another user then this error would occur. The solution would be to generate the DbContext inside the new thread or new Impersonation context.
I just closed all instances of Visual Studio and reopened my solution.
I don't know what really happened, but I had the same solution opened from two different local workspaces (one with my local changes, one with the unchanged repository source code). I work with a postgres DB, Entity Framework 6, Visual Studio 2013 and ASP.NET MVC 5.
I had a error for entity framework, but none of the above answers ended up fitting into the solution that finally worked.
My EntityFramework Code First Models and DataContext were in a Separate project from my WebAPI Main Project. My Entity Framework Project somewhere down the line of coding was set as the startup project and therefore when I was running a migration I was getting “The provider did not return a ProviderManifestToken string” ... connection issue.
Turns out that since the ConnectionString to the DB is located in the Web.config file in WebAPI Main project, that when I was running a migration the connection string was not being retrieved. By setting WebAPI project as my startProject I was able to successfully connect.

Resources