1

的背景

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

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 可以足够聪明地接受 null 值_newEntity.Parent,也可以足够聪明地读取entity.Parent.Equals为表达式而不是方法调用(在 null 的情况下失败)。

无论如何这不是问题

错误

System.NotSupportedException: Boolean Equals(System.Object)

我知道 NHibernate LINQ 不是完整的 LINQ 提供程序,也不支持实体框架支持的所有方法。所以我可以期待。显然,我可以通过首先按名称选择实体然后检查父母双方是否为空或他们是否Equals()(我重载Equals以检查 Id)来解决

问题

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

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

4

1 回答 1

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();
于 2013-03-21T09:56:06.197 回答