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

NHibernate / LINQ / filter child collection

这里有一个很好的答案。但是它使用Criteria而不是Linq

滤镜基本上是你的朋友。

正如异常消息所说,您不允许替换用cascade="all-delete-orphan"映射的集合,因此不要给p.Properties分配任何内容。这是因为NHibernate需要它的特殊集合类来知道哪些子节点被删除了。

我认为你有两种可能性:

  1. Project类中创建一个属性,返回过滤的集合(但不修改实际的Properties集合),并在任何需要过滤数据的地方使用此属性。
  2. 使用NHibernate过滤器看到这里。