W
W
WhiteNinja2017-05-30 17:04:33
C++ / C#
WhiteNinja, 2017-05-30 17:04:33

How to implement a Read-only collection in DDD using Entity Framework?

Good afternoon, colleagues!
Question about Entity Framework and Read-only implementation of a collection of related elements when using DDD (Domain Driven Design).
For example, there is an entity "department" with a list of positions in this department:

public class Department
{
  public int DepartmentId { get; private set; }
  public string DisplayName { get; private set; }
  
  // Список должностей в отделе
  protected virtual ICollection<Position> _positions { get; set; }
    public IEnumerable<Position> Positions => _positions.Skip(0);
  public static Expression<Func<Department, ICollection<Position>>> PositionsAccessor = f => f._positions;
  
  public void AddPosition(Position position)
  {
    _positions.Add(position);
  }
  
  ....
}

public class Position
{
  public int PositionId { get; private set; }
  public string DisplayName { get; private set; }
  
  public int DepartmentId { get; private set; }
  public virtual Department Department { get; private set; }
  
  ...
}

For mapping you can use:
class DepartmentConfiguration : DbEntityTypeConfiguration<Department>
{
  public DepartmentConfiguration()
  {
    HasKey(x => x.DepartmentId);
    HasMany(Department.PositionsAccessor)
      .WithRequired(x => x.Department)
      .HasForeignKey(x => x.DepartmentId)
      .WillCascadeOnDelete(true);
    
    ....
      
    ToTable("Departments");
  }
}

The implementation of the Read-only list via a static field is taken from here or here .
Everything is great, you can do Include, for example:
_dbContext.Set<Department>()
  .Where(x => x.DisplayName.StartWith("Some name"))
  .Include(Department.PositionsAccessor);

But the question is: How to implement subqueries to these most nested elements. For example, you need to get a list of departments where there are managers.
In this case, the Linq query would be something like this:
_dbContext.Set<Department>()
  .Where(x => x.Positions.Any(p => p.TypeId == Enums.PositionType.Manager)) // Это срока выдает Exception, так как Positions не является навигационным полем (им является _positions).
  .Include(Department.PositionsAccessor);

How to implement a read-only list of related entities, while leaving the ability to make normal linq queries? Perhaps there is some other good approach besides static field?
I would appreciate any help, thanks in advance!

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question