1

背景

私のモデルは次のようになります: (簡単にするために、プロパティの代わりにフィールドを記述します)

public class Entity {
    public long Id;
    public string Name;
    public Entity Parent;
}

エッセンシャル FNH マッピング

        Map(x => x.Name)
            .Not.Nullable()
            .UniqueKey("Child");

        References(x => x.Parent)
            .Cascade.None()
            .UniqueKey("Child");

SQL

create table `Entity` (Id BIGINT not null, Name VARCHAR(255) not null, Parent_id BIGINT, primary key (Id),unique (Name, Parent_id))

そして、それは結構です。同じエンティティの子の間で親近感を持ちたくありません (したがって、異なる親の 2 つのエンティティが同じ名前を持つ可能性があります)。ちなみに、null可能Parent_idであることを覚えておいてください

私は何をする必要がありますか

新しいエンティティを DB に挿入する前にチェックを実施したいと考えています。例外をキャッチする代わりに、適切な例外をスローするために、同じ名前で newcoming の親を持つエンティティが存在するかどうかを確認するクエリを起動します (ただし、パフォーマンスが低下すると思います...)。パフォーマンスにもかかわらず、LINQ プロバイダーについて何か新しいことを学ぶチャンスです。

普通の古いSQLで私はするだろう

SELECT Id FROM entity WHERE Name = ? AND Parent_id = ?

これはNULL IDを正しくサポートします

私が試したこと(そして失敗しました。そうでなければ、私はここにいません)

var exInput = (from Entity entity in entityRepository.Query()
    where entity.Name.ToLowerInvariant() == _newEntity.Name.ToLowerInvariant()
        && entity.Parent.Equals(_newEntity.Parent)
    select new { ParentName = entity.Parent != null ? entity.Parent.Name : null }).FirstOrDefault();

NHibernate は、null 値を受け入れるのに十分スマートであり、メソッド呼び出し (null の場合は失敗する) の代わりに式として_newEntity.Parent読み取るのに十分スマートであると考えました。entity.Parent.Equals

とにかくそれは問題ではありません

エラー

System.NotSupportedException: Boolean Equals(System.Object)

NHibernate LINQ が完全な LINQ プロバイダーではなく、Entity Framework がサポートするすべてのメソッドをサポートしていないことはわかっています。だから私はそれを期待することができました。明らかに、最初にエンティティを名前で選択してから、両方の親が null であるかどうか、またはそれらが( Id をチェックするためにオーバーロードした) かどうかを確認することで回避できます。Equals()Equals

質問

上記の節にできるだけ近い SQL を NHibernate に生成させたいのですがWHERE、どうすればよいですか? 使用する別の LINQ 構文はありますか、または LINQ プロバイダーを拡張する必要がありますか?

ドキュメントを見つけたLINQプロバイダーを拡張することを考えていました。私の意見では、比較のオペランドが同じ ID である場合、それらの ID を単純に一致させることができます (エンティティの 1 つがHQL で ID をnull生成する場合)。NULLこの場合、共有する実装を試みた人はいますか?

4

1 に答える 1

4

Equalsクエリでは使用しないでくださいentity.Parent == _newEntity.Parent

Linq クエリには、取得する SQL との違いもいくつかあります。次のクエリを使用してみませんか?

var result = (from Entity entity in entityRepository.Query()
              where entity.Name == _newEntity.Name && entity.Parent == _newEntity.Parent
              select entity.Id).ToArray();
于 2013-03-21T09:56:06.197 に答える