FreeSqlはどのようにSqliteのライブラリ間クエリーを実現します


FreeSqlは.NetFramework 4.6+、.NetCoreの下のORM機能ライブラリは、5つのポピュラーなデータベースMySql/SqlServer/PostgreSQL/Oracle/Sqliteをサポートする豊富な機能を提供しています.
通常のデータベースではクロスライブラリがサポートされていますが、Sqliteはデフォルトではサポートされていません.あるいは、サポートが面倒です.FreeSqlが最も関心を持っているのは汎用性、使いやすさです.ここでは、FreeSqlがどのようにSqliteクロスライブラリ操作を実現するかについて説明します.
物語はCodeFirstの自由開発で起きた
FreeSqlは、FreeSqlの名前のように、CodeFirst方式の開発プロジェクトをサポートし、推奨しています.
2つのエンティティ(記事、コメント)を次のように定義します.
class Topic {
    public Guid Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime CreateTime { get; set; }
}
[Table(Name = "xxxtb.Comment")]
class Comment {
    public Guid Id { get; set; }
    public Guid TopicId { get; set; }
    public Topic Topic { get; set; }
    public string Nickname { get; set; }
    public string Content { get; set; }
    public DateTime CreateTime { get; set; }
}

私たちはTopicのデータをメインライブラリに保存し、Commentのデータを別のライブラリ(xxctb)に保存したいと思っています.たとえばmysqlを使用して、データベースを指定しない場合、現在のデータベースの下のテーブルが操作されます.
その他ado.NetまたはORMが直面する問題(デフォルト):
1、ドライバは1つのライブラリしか開いていないか、または手動でドライバを呼び出す方法で他のライブラリを追加する必要がある.
2、プロジェクトでは複数のormを定義し、複数のデータベースのストレージとクエリーを実現する必要がある場合があります.
3、クロスライブラリテーブルクエリーを使用できません.
ユーザー使用上の問題の解決
使用習慣はFreeSqlの主な難題であり、他のデータベースでも構わない.
幸いなことに今のNETライブラリのほとんどがオープンソースになっているので、Systemを参照してください.Data.SQLite.Coreソースについてまとめました.
SQLiteConnection接続オブジェクトはOpen後、次のコマンドを実行して複数のデータベースを追加できます.
attach database [xxxtb.db] as [xxxtb];

すると、
ステップ1:Openの代わりにOpenAndAttachを使用する拡張方法を実装します.
public static void OpenAndAttach(this DbConnection that, string[] attach) {
    that.Open();

    if (attach?.Any() == true) {
        var sb = new StringBuilder();
        foreach(var att in attach)
            sb.Append($"attach database [{att}] as [{att.Split('.').First()}];\r
"); var cmd = that.CreateCommand(); cmd.CommandText = sb.ToString(); cmd.ExecuteNonQuery(); } } // ...

ステップ2:ConnectionsStringパラメータAttachsを追加
Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10

ステップ3:SqliteConnectionPool実装
1、解析Attachs;
var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase);
if (att.Length == 2) {
    //       ,   Attachs     ,          
    var idx = att[1].IndexOf(';');
    Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(',');
}

2、従来のOpen方法をOpenAndAttachに置き換える.
大功を成し遂げる
エンコーディングと実装プロセスが完了し、その後のテスト結果は、上に示す2つのエンティティタイプを使用します.
static IFreeSql sqlite = new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10")
    .UseAutoSyncStructure(true)
    .UseLazyLoading(true)
    .Build();

//    FreeSql.Repository    
//    :dotnet add package FreeSql.Repository
var topicRepository = sqlite.GetGuidRepository();
var commentRepository = sqlite.GetGuidRepository();

//      
Guid topicId = FreeUtil.NewMongodbId();
topicRepository.Insert(new Topic {
    Id = FreeUtil.NewMongodbId(),
    Title = "    1",
    Content = "    1",
    CreateTime = DateTime.Now
});

//  10     
var comments = Enumerable.Range(0, 10).Select(a => new Comment {
    Id = FreeUtil.NewMongodbId(),
    TopicId = topicId,
    Nickname = $"  {a}",
    Content = $"    {a}",
    CreateTime = DateTime.Now
});
var affrows = commentRepository.Insert(comments);

var find = commentRepository.Select.Where(a => a.Topic.Title == "    1").ToList();
//SELECT a."Id", a."TopicId", a."Nickname", a."Content", a."CreateTime" 
//FROM "xxxtb"."Comment" a, "Topic" a__Topic 
//WHERE (a__Topic."Title" = '    1')

//find     10   

次にnavicatを使用して2つのデータベースを追加して表示します.
その他の説明
1、FreeUtil.NewMongodbIdは、秩序を生成するGuid値である、FreeSqlで実現されるが、実際にはGuidを用いることができる.NewGuid、ここで私はショーの疑いを認めます.
2、文章中のコードはあまり依存していない、vs 2017+.netcore2.2 1回のテストに合格し、sqliteの優位性はインストールサービスを免除する.
3、FreeSqlはCodeFirstをサポートし、すなわち実体実行プログラムを構築すれば、テーブルが作成される.
4、FreeSql.Repositoryは拡張パッケージであり、汎用CURD倉庫層機能を実現し、ドキュメント:https://github.com/2881099/FreeSql/wiki/Repository
この機能は実はFreeSqlの初期にすでに実現して、しかしずっと過程の経験を文章に整理する時間がなくて、今日文章を書き終わって全部書いて、みんなに少しの“驚き”をもたらすことができることを望みます.FreeSqlにはもっと詳細な最適化がありますが、道行く人が一目で見抜くわけではありません.書くのが面倒だと思ったら、いいねを押してください.これも私が書き続ける原動力です.
一度見ても分からない場合は、何度も見ることをお勧めします.ありがとうございます!