NHibernate父/子关系中可空外键上的LINQ“equals”运算符 背景

NHibernate父/子关系中可空外键上的LINQ“equals”运算符 背景,linq,nhibernate,hql,linq-to-nhibernate,notsupportedexception,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

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

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

那很好。我不希望相同实体的子实体之间存在同构性,因此不同父实体的两个实体可能具有相同的名称。顺便说一句,记住Parent_id是可以为空的

我需要做什么 我想在将新实体插入数据库之前执行检查。我不想捕获异常,而是想触发一个查询,但我认为这会降低性能。。。检查是否存在具有相同名称和新来者父项的实体,以便引发适当的异常。尽管表现出色,但这仍然是一个学习LINQ提供商新知识的机会

在普通的老SQL中,我会这样做

SELECT Id FROM entity WHERE Name = ? AND Parent_id = ?
这正确地支持空ID

我尝试过但失败了,否则我就不会在这里了 我认为NHibernate可以足够聪明地接受null值作为_newEntity.Parent,也可以足够聪明地读取entity.Parent.Equals作为表达式,而不是在null情况下失败的方法调用

无论如何,这不是问题所在

错误 我知道NHibernate LINQ不是一个完整的LINQ提供者,并且不支持实体框架支持的所有方法。所以我可以预料到。显然,我可以通过首先按名称选择entity,然后检查两个父项是否都为null,或者它们是否等于I重载等于check Id来解决这个问题

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

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

不要在查询中使用Equals,只使用entity.Parent=\u 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();
在查询中不要使用Equals,只使用entity.Parent=\u 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();

请不要介意差异,我知道我在代码中做什么。我需要得到这样一个实体是否存在,但是+1表示注意。SQL只是为了说明查询的简单性。我认为==运算符不起作用,所以我不敢尝试。另外,ReSharper建议不要使用==@djechelon,因为在你的问题中,你写的尽可能接近上面的SELECT语句,所以我提到了它。关于==运算符:NHibernate始终将实体上的==运算符视为Id比较。如果查询的参数为null,它甚至可以工作,然后NHibernate将创建一个Id为null的SQL查询。我更新了问题:我想要尽可能接近WHERE子句的东西;-因为我只关注这一点,请不要介意差异,我知道我在代码中做什么。我需要得到这样一个实体是否存在,但是+1表示注意。SQL只是为了说明查询的简单性。我认为==运算符不起作用,所以我不敢尝试。另外,ReSharper建议不要使用==@djechelon,因为在你的问题中,你写的尽可能接近上面的SELECT语句,所以我提到了它。关于==运算符:NHibernate始终将实体上的==运算符视为Id比较。如果查询的参数为null,它甚至可以工作,然后NHibernate将创建一个Id为null的SQL查询。我更新了问题:我想要尽可能接近WHERE子句的东西;-因为我只关注这个
System.NotSupportedException: Boolean Equals(System.Object)
var result = (from Entity entity in entityRepository.Query()
              where entity.Name == _newEntity.Name && entity.Parent == _newEntity.Parent
              select entity.Id).ToArray();