NHibernate / LINQ / filter child collection
本文关键字:collection child LINQ NHibernate filter | 更新日期: 2023-09-27 18:03:40
我正在尝试在我的服务层返回一个父级,它有一个我需要过滤的子对象集合。只有子对象被过滤,所以即使过滤器意味着0个子对象,父对象仍然返回。
从下面的代码中可以看到,我在这里尝试使用的方法非常简单。我已经调查了其他类似的问题,但还没有得到答案。
- 我不需要过滤器发生在数据库查询,虽然如果这是可能的,它将是好的。
- 如果使用单个LINQ语句,那么过滤所有子对象仍然应该返回父(项目)。
我知道这可以通过在Mapping中添加WHERE子句来解决,但这确实允许您级联删除。
当使用下面的代码时,抛出以下异常:
带有cascade="all-delete-orphan"的集合不再被所属实体实例Project引用。属性
//实体 public class Project
{
public virtual int Id { get; set; }
private ICollection<Property> properties = new List<Property>();
public virtual ICollection<Property> Properties
{
get { return properties; }
set { properties = value; }
}
}
public class Property
{
public virtual DateTime? DateDeleted { get; set; }
}
//NHibernate映射
mapping.HasMany<Property>(x => x.Properties)
.ForeignKeyConstraintName("Project_Id")
.AsSet()
.Cascade.AllDeleteOrphan()
.OrderBy("Estate_Id");
//服务层:调用项目库。只返回具有活动属性的项目
private ProjectDto GetActiveProject(int id)
{
var p = projectRepository.Get(id);
//filter out deleted properties
if (p != null)
p.Properties = p.Properties.Where(x => x.DateDeleted == null).ToList();
return projectTransformer.Transform(p);
}
这里有一个很好的答案。但是它使用Criteria
而不是Linq
滤镜基本上是你的朋友。
正如异常消息所说,您不允许替换用cascade="all-delete-orphan"映射的集合,因此不要给p.Properties
分配任何内容。这是因为NHibernate需要它的特殊集合类来知道哪些子节点被删除了。
我认为你有两种可能性:
- 在
Project
类中创建一个属性,返回过滤的集合(但不修改实际的Properties
集合),并在任何需要过滤数据的地方使用此属性。 - 使用NHibernate过滤器看到这里。