2

I'm building a new project using Xamarin.Forms and I wanted to use SQLite to store the user data. I'm using .Net standard project. I installed the sqlite-net-pcl NuGet package by Frank A. Krueger in all 4 projects (shared code, droid, ios and uwp). I created the IFileHelper interface and the class implementing that interface in all projects, just as the documentation tells you to do. When I first launch the app I want to insert some default values in the database, but I just get an exception. I've been debugging and when the database is created on the App.xaml.cs doc it just returns null, so I don't get any database.

I've checked all code over and over and everything is fine, so I'm just wondering is sqlite-net-pcl compatible with .NET standard projects? Is there any solution for this prob?

This is the code on App.xaml.cs

static AppDatabase database;

    public App ()
    {
        InitializeComponent();

        MainPage = new MainPage();
    }

    public static AppDatabase Database
    {
        get
        {
            if (database == null)
            {
                database = new AppDatabase(DependencyService.Get<IFileHelper>().GetLocalFilePath("AppDatabase.db3"));
                System.Threading.Thread.Sleep(500);
            }
            return database;
        }
    }

I when I return the database, it just returns null, so when I create the table on the AppDatabase class, I get the exception System.AggregateException: One or more errors occurred.

readonly SQLiteAsyncConnection Database;

        public AppDatabase(string dbPath)
        {
            Database = new SQLiteAsyncConnection(dbPath);
            Database.CreateTableAsync<Stats>().Wait();
        }

I understand the exception, since the database is null I can't aggregate any table or anything at all since the database doesn't exist, but why it doesn't create the database?

This is the interface for the shared code

namespace FitApp
{
    public interface IFileHelper
    {
        string GetLocalFilePath(string fileName);
    }
}

And the class implementing the interface on the droid project:

[assembly: Dependency(typeof(FitApp.Droid.FileHelper))]
namespace FitApp.Droid
{
    public class FileHelper : IFileHelper
    {
        public string GetLocalFilePath(string fileName)
        {
            string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            return System.IO.Path.Combine(path, fileName);
        }
    }
}

Thanks

David AK
  • 125
  • 1
  • 14
  • 2
    "I just get an exception" - this is equivalent to going to the mechanic and saying "one of the lights on the dashboard lit up, but I don't know which one". That's just not helpful. You need to tell us WHICH specific exception occurred, which line caused it, and include the relevant portions of your code. – Jason Jun 03 '18 at 14:28
  • 1
    A stack trace/log would help as well – Hichame Yessou Jun 03 '18 at 14:29
  • 1
    An AggregateException means multiple errors occurred - you need to examine the Exception object to get the details of the specific errors – Jason Jun 03 '18 at 15:26

1 Answers1

1

I found this page to really help in getting started with SQLite with Xamarin. Xamarin - Working with Local Databases in Xamarin.Forms Using SQLite

Note this page is not using the async database.

My implementation which works. Initialisation;

public SQLiteAsyncConnection AsyncDb { get; private set; }

    public App ()
    {
        InitializeComponent();
        AsyncDb = DependencyService.Get<IDatabaseConnection>().AsyncDbConnection();
}

Interface;

public interface IDatabaseConnection
{
    SQLite.SQLiteAsyncConnection AsyncDbConnection();
}

Droid Implementation;

public class DatabaseConnection_Droid : IDatabaseConnection
{
    public SQLiteAsyncConnection AsyncDbConnection()
    {
        var dbName = "DiceyData.db3";
        var path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), dbName);
        return new SQLiteAsyncConnection(path);
    }

}

Then you can operate on the appwide property, eg; await ((App)Application.Current).AsyncDb.CreateTableAysnc<YourTypeHere>();

Lindsay
  • 575
  • 8
  • 18
  • FYI: You should be using the actual Android database location, via the Android Content API `GetDatabasePath` – SushiHangover Jun 04 '18 at 02:16
  • @SushiHangover, Thanks for the feedback. I'm not overly familiar with Android at all, hence using Xamarin for the heavy lifting. Are you able to elaborate on what the difference is between the path method I'm using and the one you've suggested? – Lindsay Jun 04 '18 at 23:31