5

この方法を考えると:

internal static IEnumerable<Entity> GetByParentImpl<Entity, TKey>(this ICanGetByParent<Entity, TKey> self, TKey parentId, string fieldName) 
    where Entity : class 
{
    RepositoryBase<Entity> rb = (RepositoryBase<Entity>)self;
    rb.unitOfWork.Begin();

    var entities = rb.unitOfWork.Session.QueryOver<Entity>()
        .Where(e => EqualityComparer<TKey>.Default.Equals(GetId<Entity, TKey>(e, fieldName), parentId))
        .List();

    return entities;
}

そしてこのヘルパー:

private static TKey GetId<Entity, TKey>(object obj, string fieldName) where Entity : class
{
    TKey id = default(TKey);

    switch(id.GetType().Name) {
        case "Int32":
            break;
        case "Guid":
            id = (TKey)TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString((string)typeof(Entity).GetField(fieldName).GetValue(obj));
            break;
    }

    return id;
}

linqステートメントで次の例外が発生します。

認識されないメソッド呼び出し:System.Collections.Generic.EqualityComparer`1 [[System.Guid、mscorlib、Version = 4.0.0.0、Culture = neutral、PublicKeyToken = b77a5c561934e089]]:Boolean Equals(System.Guid、System.Guid)

これは何を意味するのでしょうか?これを正しくデバッグする方法すらわかりません。上記のコードが機能していることを誓ったかもしれません...

4

2 に答える 2

3

linqについて、このような方法でデータベースプロバイダーと比較することはできません。プロバイダーはこれを式ツリーに変換できません。したがって、.ToArray()の後に使用するか Expression<Func<RegisterCardBase, bool>>、ラムダの代わりにWhereを指定する必要があります。

PS:なぜGuidでそんなに奇妙な行動をしているのですか?データベースにどのように保存されますか?

于 2012-08-09T15:55:30.947 に答える
2

NHibernate の Linq プロバイダーは、Linq クエリを HQL に変換し、最終的に SQL に変換しようとします。Where メソッドにあるラムダ式は、デフォルトでは NHibernate ではサポートされていません。

ただし、NHibernate Linq プロバイダーは拡張可能です。サポートされていないさまざまな式を処理するための独自の拡張機能を作成できます。

Alessandro Giorgettiには、Linq プロバイダーを拡張して option をサポートする方法に関する良いサンプルがString.EqualsありStringComparisonます

編集

NHibernate Linq ではなく、QueryOver を使用していることに気付きました。おそらくタグを削除する必要があります。に切り替えると、私の答えは多少関連しますsession.Query<Entity>()Idそれでも、変換して で使用するためのアプローチを再考するかもしれませんWhere

于 2012-08-09T16:04:29.433 に答える