15

私は自分の仕事の多くを単純化する天才タイプについて学びましたが、私の好みのORMはそれを認識していないようです。

ServiceStackOrmLiteがSQLServerで認識できるようにするための回避策はありHierarchyIdますか?変更するファイルに関する提案や、続行するためのヒントはありますか?

編集 :

これが問題のより良い例です。私は次のクラスを持っています:

public class MyClass
{
    public int Id { get; set; }
    public SqlHierarchyId HierarchyId { get; set; }
}

SqlHierarchyIdは、カスタムSQLServerデータ型です。OrmLiteは、次のクラスを生成します。

最初のMyClassレンダリング

[StringLength(255)]おかしなことに、プロパティの属性を使用すると、varchar(255)代わりにタイプが取得されます。

2番目のMyClassレンダリング

ここでテーブルを手動で変更し、違いを示すために列のデータ型を追加しました。3番目の列のデータ型に注意してください。

SqlHierarchyId

表現を持つことは、 C#内で変換できるためvarchar、他のDBMSでもまったく問題ありませんが、SQL Serverでは、対応するデータ型と一致させることが望ましいです。これにより、ビューの作成が簡単になります(データ型の組み込み関数のため)。hierarchyid

このタイプはEF4でサポートされていないことを知っています(5についてはわかりません)。また、GitHubでOrmLiteDialectProviderBase.csファイルを参照すると、サポートされているADO.NETデータ型のリストを確認できます。

私の簡単な質問は次のとおりです。これはADO.NETによる強力な制限ですか、それともOrmLiteでいつか見られる可能性がありますか?何か提案があれば、この部分の拡張を喜んでお手伝いします。

4

1 に答える 1

1

ADO.NET は hierarchyid 型をサポートしています。例はここにあり、ADO.NET は Sql Server から値を hierarchyid として直接読み取ることができますが、パラメータを文字列としてサーバーに渡す必要があることを示しています。

hierarchyid タイプのメソッドのサポートを ORM フレームワークに追加すると、ORM API と RDMS の間の抽象化が壊れます。これが、そのような機能が Entity Framework に追加されていない理由だと思います。

データベースに階層の文字列表現を保持し、データベースと C# クラスの両方で計算されたプロパティとして hierarchyid バージョンを保持することで問題を回避できます。計算された C# プロパティを ORM マッピングから除外する必要があります。

たとえば、テーブルの列は次のように宣言されます。

[SqlHierarchyId] AS ([hierarchyid]::Parse([HierarchyId])) PERSISTED 

そしてあなたのクラスは:

public class MyClass {

    public string HierarchyId {
        get;
        set;
    }

    [Ignore]
    public SqlHierarchyId SqlHierarchyId {
        get {
            return SqlHierarchyId.Parse(new SqlString(HierarchyId));
        }
        set {
            HierarchyId = value.ToString();
        }
    }

}

これにより、.Net レイヤーからの更新が保持され、hierarchyid メソッドを使用して SQL Server でクエリを作成し、.Net レイヤーで実体化されたオブジェクトを操作できるようになります。

ORM レイヤーの文字列表現に対してクエリを作成する必要がありますが、これでも hierarchyid ヘルパー メソッドの一部を利用できます。次に例を示します。

public IEnumerable<MyClass> GetDescendants(MyClass node) {

    string currentLocation = node.HierarchyId;
    string followingSibling 
        = node.SqlHierarchyId.GetAncestor(1)
              .GetDescendant(node.SqlHierarchyId, SqlHierarchyId.Null)
              .ToString();

    return db.Select<MyClass>(n => n.HierarchyId > currentLocation 
                                && n.HierarchyId < followingSibling);

}

ORMLite の構文が間違っていたらすみません。

于 2015-02-25T05:12:47.150 に答える