With Xamarin Forms, how can I create my SQLite connections in shared code?

Ala*_*an2 5 c# xamarin xamarin.forms

I recently noticed a couple of articles that mentioned creating SQLite connections all in common code. Is this something new as I have always done it this way with an interface:

Is there a way this could all be accomplished in common code rather than in the implementation below that requires code in Common, iOS and Android?

Common code:

namespace Memorise
{
    public interface ISQLiteDB1
    {
        (SQLiteConnection, bool) GetConnection();
    }
}
Run Code Online (Sandbox Code Playgroud)

iOS code:

[assembly: Dependency(typeof(ISQLiteDB_iOS))]
namespace Memorise.iOS
{
    public class ISQLiteDB_iOS : ISQLiteDB
    {
        public (SQLite.SQLiteConnection, bool) GetConnection(string _dbName)
        {
            bool newDb = false ;
            var sqliteFilename = _dbName;
            string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            string libraryPath = Path.Combine(documentsPath, "..", "Library");

            Debug.WriteLine(documentsPath);
            Debug.WriteLine(libraryPath);

            var path = Path.Combine(libraryPath, sqliteFilename);
            switch (_dbName)
            {
                case CONST.DB1Name:
                    if (File.Exists(path))
                    {
                        newDb = false;
                        File.Delete(path);
                    }
                    else
                    {
                        newDb = true;
                    }
                    File.Copy(sqliteFilename, path);

                    break;
                case CONST.DB2Name:
                    if (File.Exists(path))
                    {
                        newDb = false;
                    }
                    else
                    {
                        newDb = true;
                        File.Create(path);
                    }

                    break;
                case CONST.DB3Name:
                    if (File.Exists(path))
                    {
                        newDb = false;
                    }
                    else
                    {
                        newDb = true;
                        File.Copy(sqliteFilename, path);
                    }
                    break;
            }
           
            return (new SQLite.SQLiteConnection(path), newDb);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Android Code:

[assembly: Dependency(typeof(SQLiteDB1_Android))]

namespace Memorise.Droid
{
    public class SQLiteDB1_Android : ISQLiteDB1
    {
        public (SQLite.SQLiteConnection, bool) GetConnection()
        {
            bool newDb;
            var sqliteFilename = "db1.db3";
            string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
            var path = Path.Combine(documentsPath, sqliteFilename);
            if (File.Exists(path))
            {
                newDb = false;
                File.Delete(path);
            }
            else
            {
                newDb = true;
            }
            FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            ReadWriteStream(Android.App.Application.Context.Assets.Open(sqliteFilename), writeStream);
            return (new SQLite.SQLiteConnection(path), newDb);
        }

        void ReadWriteStream(Stream readStream, Stream writeStream)
        {
            int Length = 256;
            Byte[] buffer = new Byte[Length];
            int bytesRead = readStream.Read(buffer, 0, Length);
            while (bytesRead > 0)
            {
                writeStream.Write(buffer, 0, bytesRead);
                bytesRead = readStream.Read(buffer, 0, Length);
            }
            readStream.Close();
            writeStream.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Nik*_*hil 2

正如我所看到的,您有两个数据库文件,db1 和 db2。另外,我可以看到 db1 是从 Project Assests 复制并粘贴到本地文件夹中的。因此,您需要将文件db1.db3放在Resources文件夹中并将其标记为EmbeddedResource。这一步很重要。

其余代码可以简化并更改为:-

    public DataManager()
    {
        var db1Path = Path.Combine(BasePath, CONST.DB1Name);
        newDb1 = !File.Exists(db1Path);
        if (newDb1)
        {
            var assembly = IntrospectionExtensions.GetTypeInfo(typeof(DataManager)).Assembly;
            Stream stream = assembly.GetManifestResourceStream("YourProjectName.Resources.db1.db3");
            using (var db1SourceStream = new FileStream(db1Path, FileMode.Create, FileAccess.ReadWrite))
            {
                stream.CopyTo(db1SourceStream);
                db1SourceStream.Close();
            }
        }
        db1 = new SQLiteConnection(db1Path);

        var db2Path = Path.Combine(BasePath, CONST.DB2Name);
        newDb2 = !File.Exists(db2Path);
        db2 = new SQLiteConnection(db2Path);
        db2.TimeExecution = true;
    }
Run Code Online (Sandbox Code Playgroud)