Adding condition to mapping for child collection in Entity Framework 6 similar to NHibernate's "where"

c# entity-framework entity-framework-6 nhibernate

Question

NHibernate includes awhere a property mapping that enables you to set a condition that influences how data is retrieved from the database. For instance, I could map it as follows if I wanted to implement a soft delete and exclude all deleted objects from a set:

FluentNHibernate

// in class ParentMap : ClassMap
HasMany(x => x.Children).Where("IsDeleted = 0");

Hbm.Xml

<class name="Parent" table="[Parents]">
    <bag cascade="all" lazy="true" name="Children" where="IsDeleted = 0">
        <!-- rest of map here -->
    </bag>
</class>

Exists a similar feature in Entity Framework 6?

The closest thing I could find was a library by the name of EntityFramework.Filters, which allows you to create global filters for properties, but it doesn't appear to function when that property is a collection.


Let's imagine I have a class that has a collection of objects that have a recursive child entity relationship to further illustrate the need for such a mapping (i.e., a collection of objects of the same type). They adhere to this fundamental framework:

public class ReportOutline
{
    public long Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }    
    public virtual ICollection<OutlineItem> OutlineItems { get; set; }
}

public class OutlineItem
{
    public long Id { get; set; }
    public string Name { get; set; }

    public long ReportOutlineId { get; set; }
    public long? ParentOutlineItemId { get; set; }    

    public virtual ReportOutline ReportOutline { get; set; }
    public virtual OutlineItem ParentOutlineItem { get; set; }    

    public virtual ICollection<OutlineItem> OutlineItems { get; set; }
}

And using the EF Fluent API, these are mapped as follows:

modelBuilder.Entity<ReportOutline>()
    .HasKey(o => o.Id)
    .HasMany(o => o.OutlineItems)
    .WithRequired(i => i.ReportOutline)
    .HasForeignKey(i => i.OutlineId);

modelBuilder.Entity<OutlineItem>()
    .HasKey(p => p.Id)
    .HasMany(p => p.OutlineItems)
    .WithOptional(c => c.ParentOutlineItem)
    .HasForeignKey(c => c.ParentOutlineItemId);

My records appear OK and the database structure is right as a result. Here is an illustration of what theOutlineItems a table with two objects on it would appear to beReportOutline , assuming there were two additional things (a total of four):

Id    Name           ReportOutlineId    ParentOutlineItemId
1     Introduction   1                  NULL
2     Pets           1                  NULL
3     Cats           1                  2
4     Dogs           1                  2

once theReportOutline receives loading via theDbContext however, becauseReportOutlineId similar to the outlineId , theReportOutline.OutlineItems is filling up with each of the four components. As a result, the parent items and the main outline itself are both accompanied by the sub-items:

Title:  My Report
Author: valverij

I.  Introduction  (Id: 1)
II. Pets          (Id: 2)
    A. Cats       (Id: 3)
    B. Dogs       (Id: 4)
III. Cats         (Id: 3) <--- Duplicated
IV.  Dogs         (Id: 4) <--- Duplicated

If I were to use FluentNhibernate in conjunction with NHibernate, I could define awhere the entity mapping is subject to a condition, so thatReportOutline.OutlineItems Parent items are pulled by only

// in ReportOutlineMap
HasMany(x => x.OutlineItems).Where("ParentOutlineItemId IS NULL");

Without it, I'd have to remember to access only.ReportOutline through a pre-written query that specifically addresses theOutlineItem collection.

1
4
12/8/2014 6:44:47 PM

Popular Answer

ZZZ_tmp
0
9/8/2015 3:12:21 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow