我的模型如下所示:(为简单起见,写字段而不是属性)
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
标识)。在这种情况下,有没有人尝试过分享实现?
答案 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();