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>>into Where 而不是 lambda。

PS:你为什么用Guid做这么奇怪的动作?它是如何存储在数据库中的?

于 2012-08-09T15:55:30.947 回答
2

NHibernate 的 Linq 提供程序尝试将 Linq 查询转换为 HQL,并最终转换为 SQL。NHibernate 默认不支持 Where 方法中的 lambda 表达式。

但是,NHibernate Linq 提供程序是可扩展的。您可以创建自己的扩展来处理各种不受支持的表达式。

Alessandro Giorgetti有一个很好的示例,介绍了如何扩展 Linq 提供程序以String.Equals支持StringComparison选项

编辑

我刚刚意识到您使用的是 QueryOver,而不是 NHibernate Linq。您可能应该删除标签。如果您切换到session.Query<Entity>(). 不过,您可能会重新考虑IdWhere.

于 2012-08-09T16:04:29.433 回答