2

Entities: Address and Market:

public class Address
{
    ...

    // Navigation properties
    public Guid MarketId { get; set; }
    public Market Market { get; set; }
}

public class Market
{
    ...

    // Navigation properties
    public Guid AddressId { get; set; }
    public Address Address { get; set; }
}

Relation rules:

  1. Each Market has an Address and a Market cannot exist without an Address. Address is required
  2. The user cannot delete an Address that belongs to a Market
  3. When the user deletes a Market, its Address must be deleted automatically

Is it possible to configure the above relation with Entity Framework Core and Fluent API?

I've read about one-to-one relationships with EF Core and I learned that I need to say which entity is the principal and which is the dependent. And I must use Fluent API to do that.

I've tried two approaches:

  1. Market as principal: with this approach, only rule 3 is valid. I can add a Market without an Address (breaks the rule 1). An existing Market is needed to add an Address. And the user can delete the Address that belongs to a Market (breaks the rule 2).
builder.Entity<Market>()
  .HasOne<Address>(m => m.Address)
  .WithOne(a => a.Market)
  .HasForeignKey<Address>(a => a.MarketId)
  .OnDelete(DeleteBehavior.Cascade);
  1. Address as principal: with this approach, only the rule 3 is broken. The user cannot add a Market without an Address, in other words, an existing Address is needed to add a Market. The user cannot delete an Address that belongs to a Market because on the DeleteBehavior, the relation was set as Restrict. But if the user deletes a Market, its Address won't be deleted automatically. The API must handle that.
builder.Entity<Market>()
  .HasOne<Address>(m => m.Address)
  .WithOne(a => a.Market)
  .HasForeignKey<Market>(m => m.AddressId)
  .OnDelete(DeleteBehavior.Restrict);

I'm not sure if I've set the relations correctly or if it's just an EF Core limitation. Any help?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sérgio Damasceno
  • 657
  • 1
  • 8
  • 18
  • Sounds like [Owned Enttiy Types](https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities) would also be a good fit. – Christian Held Apr 26 '20 at 19:29
  • EF core is totally unequipped in the area of required one-to-one relationships. One-to-one, table splitting, owned type, they all have problems enforcing the required child or dependent entity. Maybe it's because a relational database can't enforce it, but at least EF could *validate* it. – Gert Arnold Apr 29 '20 at 19:25

1 Answers1

-1

The Fluent API should not be able to meet your current needs, because your needs are contrary to normal needs.

According to normal logic, Address is the main table, it not be attached to the Market table, so when you delete the Market table data, you should not affect the Address table.

However, if you must delete, you have two other alternatives.

The first one is to delete the corresponding data directly in the code logic after you delete the Market's data, you can get the Address data according to the currently deleted Market data's foreign key AddressId and then delete it.

Second, you can create a trigger in the database to ensure that when deleting Market data, the corresponding Address data is also deleted, the logic is the same as the first.

LouraQ
  • 6,443
  • 2
  • 6
  • 16