简体   繁体   中英

EF Core - multiple parents with a list of the same child (code first)

Is there any way to represent something like this:

public abstract class DbEntity
{
    [Key]
    public string Id { get; set; } // <-- a GUID-String created by the domain
}

public class Carrier : DbEntity
{
    public string Name { get; set; } = default!;
    public ICollection<Address> Addresses { get; set; }
}

public class Customer : DbEntity
{
    public string Name { get; set; } = default!;
    public ICollection<Address> Addresses { get; set; }
}

public class Address
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string? Street { get; set; }
}

Entity Framework will always create the address-table like this:

  • Id
  • Street
  • CarrierId
  • CustomerId

The problem is, that multiple tables will have an list of addresses (not just two) and I really don't want something like:

  • Id
  • Street
  • Parent1Id
  • Parent2Id
  • Parent3Id
  • Parent4Id
  • ...

I've also tried to set up my entities like this:

_modelBuilder?.Entity<Carrier>()
              .HasMany(entity => entity.Addresses);

Which will also create the navigation properties on the child.

I'm also understanding why, because its a many-to-one relationship and the child needs to know his parent.

However I really have no ideas to solve my 'problem'.

I was thinking about creating multiple classes/tables for my addresses like 'CustomerAddress' and 'CarrierAddress' (which inheritance from 'address'), but creating a new address table for every parent.. feels wrong?

Is this really the right way or can I solve this somehow else or is something considered 'good practise' for such cases?

You can use Address class with a generic type, but this will generate multiple tables with different names like this:

Address<Parent1>
Address<Parent2>
Address<Parent3>

If this is ok with you, you can modify Address class as:

public class Address<TParent>
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string? Street { get; set; }
    public TParent Parent { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM