Open Closed

Why we should not add navigation properties to other aggregate roots #4108


1
enes.koroglu created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.

If you're creating a bug/problem report, please include followings:

  • ABP Framework version: v5.3.3
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Steps to reproduce the issue:"

I have some entities like below:

public class Order :AggregateRoot<Guid>
{
    public string Name { get; set; }
    public string Address { get; set; }
    public ICollection<OrderLine> Lines { get; set; }
}
public class OrderLine:Entity<Guid>
{
    public Guid ProductId { get; set; }
    public Guid OrderId { get; set; }
    public int Quantity { get; set; }
    public Product Product { get;}
}
public class Product:AggregateRoot<Guid>
{
    public string Name { get; set; }
    public string Description { get; set; }
}

public class EfCoreOrderRepository : EfCoreRepository<CommonDbContext, Order, Guid>, IOrderRepository
{
    public async Task<Order> GetWithNavigationPropertiesAsync(Guid id)
    {
        var query = from order in (await GetDbSetAsync()).Include(p => p.Lines).ThenInclude(s => s.Product)
                    where order.Id == id
                    select order;
        return await query.SingleAsync();
    }
}

I've added Product as a navigation property to OrderLine entity. But as we see in docs there is a section which says:

Do always reference to other aggregate roots by Id. Never add navigation properties to other aggregate roots.

  1. What is the main reason of this suggestion, could you please give more detail?
  2. If our way is wrong, how should we get Order/Lines and Product details on GetWithNavigationPropertiesAsync method.

1 Answer(s)
  • 0
    maliming created
    Support Team

    hi

    Do always reference to other aggregate roots by Id. Never add navigation properties to other aggregate roots.

    What is the main reason of this suggestion, could you please give more detail?

    1. This rule makes it possible to implement the serializability principle.
    2. It also prevents different aggregates manipulate each other and leaking the business logic of an aggregate to one another.

    It's just a recommended practice, but you don't have to follow it exactly.

    If our way is wrong, how should we get Order/Lines and Product details on GetWithNavigationPropertiesAsync method.

    This requires an additional query (byId).