Search code examples
c#entity-framework-coredomain-driven-design

How can I make Ef Core totally ignore an object who wraps other properties inside an Entity


I'm trying to make EfCore ignore a wrapping object similarly to the owned type concept.

How can I turn this object:

public class Entity
{
    public Guid Id { get; set; }

    public object SomeProperty { get; set; }
    public ICollection<Item> Items { get; set; }
    public ICollection<OtherItem> OtherItems { get; set; }
}

public class Item
{
    public Entity Entity { get; set; }
    public Guid EntityId { get; set; }
}

public class OtherItem
{
    public Entity Entity { get; set; }
    public Guid EntityId { get; set; }
}

Into this object

public class Entity
{
    public Guid Id { get; set; }

    public Aggregate Aggregate { get; set; } // This should not be mapped to the Database but only the properties
}

[Owned] // I think this is what i'm looking for
public class Aggregate
{
    public object SomeProperty { get; set; }
    public ICollection<Item> Items { get; set; }
    public ICollection<OtherItem> OtherItems { get; set; }

    public void SomeUsefulFunction()
    {
        // do Something Useful on the Aggregate
    }
}

I would like EfCore to completely ignore the Aggregate object and threat his properties as if they were from the entity object. I thought the concept of owned entities was exactly this but I get the following error:

Unable to determine the relationship represented by navigation 'Aggregate.OtherItems' of type 'ICollection<OtherItem>'. Either manually configure the relationship, or ignore thi
s property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Solution

  • Like this?

    public class Entity
    {
        public Guid Id { get; set; }
        
        public Aggregate Aggregate => new Aggregate(this);
        protected object SomeProperty { get; set; }
        protected ICollection<Item> Items { get; set; }
        protected ICollection<OtherItem> OtherItems { get; set; }
    }
    
    public class Aggregate
    {
        public object SomeProperty => _entity.SomeProperty;
        public ICollection<Item> Items => _entity.Items;
        public ICollection<OtherItem> OtherItems => _entity.OtherItems;
        
        public Aggregate(Entity entity)
        {
           _entity = entity;
        }
        public void SomeUsefulFunction()
        {
            // do Something Useful on the Aggregate
        }
    }
    
    
    public class SampleContext : DbContext
    {
        public DbSet<Entity> Entities { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Entity>().Ignore(c => c.Aggregate);
        }
    }
    

    PS Just showing how to get, you can easly adapt it to use set too.