在NHibernate父/子关系中,LINQ“等于”运算符可以为空的外键

时间:2013-03-21 09:26:53

标签: linq nhibernate hql linq-to-nhibernate notsupportedexception

背景

我的模型如下所示:(为简单起见,写字段而不是属性)

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))

那没关系。我不希望相同实体的子项之间存在完全性(因此不同父项的两个实体可能具有相同的名称)。顺便提一下,请记住Parent_id可以为空的

我需要做什么

我想在将新实体插入数据库之前强制执行检查。而不是捕获异常我想触发一个查询(但我认为它会降低性能......)来检查是否存在具有相同名称和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可以足够聪明地接受空值为_newEntity.Parent,并且足够智能地将entity.Parent.Equals作为表达式而不是方法调用(在null的情况下失败)。< / p>

无论如何这不是问题

错误

System.NotSupportedException: Boolean Equals(System.Object)

我知道NHibernate LINQ不是一个完整的LINQ提供程序,并且不支持Entity Framework支持的所有方法。所以我可以期待。显然,我可以解决方法,首先按名称选择实体,然后检查父项是否为空或是否Equals()(我重载Equals以检查ID)

问题

鉴于我希望NHibernate尽可能地生成与上述WHERE子句尽可能接近的SQL,我该怎么办?是否要使用不同的LINQ语法,还是应该扩展LINQ提供程序?

我正在考虑扩展LINQ提供程序,我已经找到了一些文档。我认为,如果比较的操作数具有相同的标识,我们可以简单地匹配它们的ID(如果其中一个实体是null在HQL中生成NULL标识)。在这种情况下,有没有人尝试过分享实现?

1 个答案:

答案 0 :(得分: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();