ServiceStack ORMLiteとDapperは連携しています

c# dapper ormlite-servicestack

質問

これは私の3日目のServiceStack ORMLiteでの実験です。以前はDapperだけで動作していた私のサンプルプロジェクトは、DapperとServiceStack ORMLiteの両方を組み合わせたもので、両方の世界を最大限に活用しています。

昨夜、私はDapperの質問に苦しんでいました。基本的にORMLiteのコードが入る前にokを実行していた4つのテーブルを選択する選択です。オブジェクトに対するテーブルマッピングのために何度も失敗しています。それはオブジェクトに間違った値を割り当てるだけです。

私は一時的な回避策として、DapperのQueryMultipleを使用してSQL結合を使わずに4つの選択肢のそれぞれを実行していましたが、後でC#で結果を1つずつ結合しました。

笑わないでください。私はこれがもちろん、最高の解決策ではないことを知っています。それでもまだDBへの1回のトリップが行われますが、自然な感じはしません。行数が最も多くなると、パフォーマンス上の問題になります。

今朝私は問題の原因を見つけたと思います。ORMLiteを使用してテーブルを作成して作成していますが、フィールドオーダーが期待通りではないことに気付きました。 ORMLiteコードの前に手動でSQLスクリプトを実行したので、フィールドの順序を決めました。私のプロジェクトはMySql、Postgresql、そしてSQL Serverを最終的なユーザの希望としてサポートする必要があるので、このようなスクリプトの3つのバージョンを同期させておくのは苦労でしょう。 ORMLiteを使ってこのプロセスを自動化し、もちろんそれを活用したいと思います。

さて、私の理論について説明してみましょう。あなたが専門家かどうかは、私が正しいかどうかを判断するかもしれません。結合を使用するDapperのクエリは、各テーブルの結果を分割して、命名規則に基づいて各クラスにマッピングします。 "Id"または "id"フィールドがテーブルの最初のフィールドであると想定します。

私はDapperに、 "Id"の代わりにPKとして "IdProduct"という命名規則に従わないテーブルを扱う "SplitOn"オプションがあることを知っていますが、私の場合は本当に何の制御もしていないので、 ORMLiteのCreateTable関数でのフィールドの順序それは "id"が真ん中にあることで終わる可能性があり、私が今持っているのと同じ問題を引き起こします。

たぶん私のコードを見れば、もっと手がかりを与えることができます。これは、ORMLiteの前で正常に動作していたコードです。

        using (var conn = this.ConnectionString.OpenDbConnection())
        {
            string sql = @"
                select  *
                from    insumo i
                join    unidadmedida um on um.id = i.idum
                join    lineainsumo l on l.id = i.idlinea
                left outer join archivo a on a.id = i.idimagen;";

            var insumos = conn.Query<Entities.Insumo, Entities.UnidadMedida,
                Entities.LineaInsumo, Entities.Archivo, Entities.Insumo>(sql, (i, um, l, a)
                    =>
                    {
                        i.UnidadMedida = um; i.Linea = l; i.Fotografia = a ?? new Entities.Archivo();
                        return i;
                    }).ToList(); //Dapper

            return insumos;
        }

これは一時的な回避策です。

        using (var conn = this.ConnectionString.OpenDbConnection())
        {
            string sql = @"
                select * from insumo;
                select * from unidadmedida;
                select * from lineainsumo;
                select  a.*
                from    archivo a
                join    insumo i on i.idimagen = a.id;";


            var q = conn.QueryMultiple(sql); //Dapper
            var insumos = q.Read<Entities.Insumo>().ToList();
            var ums = q.Read<Entities.UnidadMedida>().ToList();
            var lineas = q.Read<Entities.LineaInsumo>().ToList();
            var archivos = q.Read<Entities.Archivo>().ToList();

            foreach (var i in insumos)
            {
                i.UnidadMedida = ums.FirstOrDefault(c => c.Id == i.IdUm);
                i.Linea = lineas.FirstOrDefault(c => c.Id == i.IdLinea);
                i.Fotografia = archivos.FirstOrDefault(c => c.Id == i.IdImagen) ?? new Entities.Archivo();
            }

            return insumos;
        }

私はORMLiteのコードに探していたし、機能ToCreateTableStatementは私の問題を解決するために変更するための場所でもそうです。おそらく、クラス定義の各フィールドに属性を追加して、フィールド作成の希望の順序が機能することを述べるのでしょうか?

私はこれをFieldDefinitionコードに追加することを考えていました:

public bool FirstField { get; set; }

そして、C#フィールドを次のように飾る属性を追加する:

[Alias("name")]
public string Name { get; set; }

[Alias("id")]
[PrimaryKey]
[FirstField(true)]
public int Id { get; set; }

その後、フィールドの作成時に、そのようなプロパティの値にコードが続き、テーブル上の最終フィールドの位置を制御することができます。

私が正しい道に入っているかどうか私に教えてください。もしかするともう一つの選択肢があるかもしれません。

前もって感謝します。

受け入れられた回答

ORMLiteのソースコードを変更するのではなく、すべてのクラスの抽象IDをオーバーライドする方が簡単です。

プロジェクトのスケジュールは、別のアプローチを試みるために狭いです。おそらく、次のもののために、@ミツが親切に示唆しているものを試す時間を見つけることができます。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow