It's possible (perhaps even likely) that I'm mixing up terminology here. So let me explain the idea...
Currently I have an Entity Framework 6 code-first kind of approach, with some persistence-ignorant models and some interfaces for IUnitOfWork
and IEntityRepository
which abstract DbContext
and DbSet<Entity>
respectively. And naturally it's "wired up" to the database via the fluent mapping syntax. So for a child object on the Entity
model:
public IList<Field> Fields { get; set; }
I would have a mapping such as:
HasMany(e => e.Fields)
.WithRequired(f => f.Entity)
.HasForeignKey(f => f.EntityId)
.WillCascadeOnDelete(false);
This same parent/child relationship continues through a sizable graph of objects under the Entity
aggregate root. And often times in the application I find that I need to iterate over child objects for various reasons. When I do this I often have to ignore certain elements (ones which are soft-deleted, for example), which means I'm materializing records from the database which I don't need.
So what I'm wondering (and so far my searching/tinkering hasn't found a solution) is if there's any way to apply some sort of logic directly to a field mapping which would result in DB-side filtering when lazy-loading that property. At its simplest, picture a .Where()
clause on the fluent mapping above.
For example, I might have an expression tree as a static property on the Field
model:
public static Expression<Func<Field, bool>> IsActive =
f => f.Versions.OrderByDescending(v => v.VersionDate)
.FirstOrDefault.IsActive == true;
If I were to use this in a .Where()
clause directly in the DbSet<Field>
it might look like:
var activeFields = db.Fields.Where(Field.IsActive);
Then when the data is materialized, the expression tree logic is applied DB-side making the whole thing a little less chatty with the database. This could perhaps be as a separate property on the model:
public IList<Field> AllFields { get; set; }
public IList<Field> ActiveFields { get; set; }
Each with their own mapping. Additional logic could be mapped to additional fields. Ideally the point here is just to offload as much of the querying logic as possible to the database. Maybe there's some technique for creating calculated fields in Entity Framework which offload their logic to the database, provided that the logic can be expressed in a Linq To Entities expression?