背景
私のモデルは次のようになります: (簡単にするために、プロパティの代わりにフィールドを記述します)
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
この場合、共有する実装を試みた人はいますか?