efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Allow moving the navigation and/or the FK to an owned type for a relationship that involves the principal

Open ethanresnick opened this issue 4 years ago • 2 comments

Similar to #24535, I have an entity that uses an owned type to group some of its properties. I'd like one of the properties in the owned type to be the parent side of a to-many relationship. My understanding is that #24535 was closed because it would violate DDD semantics to have the dependent side of the relationship point back to the owned type (rather than it pointing to the aggregate root). So, what I'm requesting here is that it should still be possible to set up this relationship, and then either:

  1. The dependent side should be able to point back to the owning entity, rather than the owned type. If I understood #24535 correctly, @AndriySvyryd suggested there that this would be a reasonable thing to do semantically, but it's not something that's currently supported.

  2. Alternatively, it could/should be possible to simply not have the dependent side refer back to anything (a uni-directional relationship).

Here's a toy model to show what I'm talking about:

public class Shipment 
{
   // ... lots of properties ...
   
   public InsurancePolicy InsurancePolicy { get; set; }
}

[Owned]
public class InsurancePolicy
{
  // ... coverage limits etc. ...
  // In this hypothetical, a new policy is issued for each Shipment, so it really is Owned.

  public ICollection<Insurer> Insurers 
}

// an entity
class Insurer
{
  public int Id { get; set; }
}

I'm proposing that it should be possible to set up the above model, and the Insurer entity would either have a property holding all the shipments (not policies) where the insurer occurs, or the Insurer entity would have no property at all referencing the shipments or policies it appears in.

Of course, I can work around this by flattening the Shipment entity so that all the insurance policy–related properties appear on it directly with a prefix, as in InsurancePolicyCoverageLimit, InsurancePolicyIssuanceDate, and (tada) InsurancePolicyInsurers. But that just removes the organizational and encapsulation/business-logic-enforcing value that I could've gotten by putting the InsurancePolicy data into a class.

Moreover, while the "flatten with prefix" workaround is at least available in the above case, it doesn't work at all if Shipment can have more than one insurance policy. (That scenario gets more complex from a relational modeling POV: it seems like the insurance policies would have to live in a separate table from the shipments, and would need a composite key that includes the shipment id; then, an insurer-to-insurance-policy join table would reference that composite key. Despite that complexity, though, there doesn't seem to be anything logically/semantically wrong that should preclude the Shipment from owning many policies, each of which can reference multiple insurers.)

ethanresnick avatar Nov 02 '21 02:11 ethanresnick

/cc @AndriySvyryd

ajcvickers avatar Nov 02 '21 13:11 ajcvickers

Yes, this makes sense. We'll consider it as part of #1985

AndriySvyryd avatar Nov 05 '21 00:11 AndriySvyryd