Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Core 2.0 - Circular Dependency with required FK on either end

I have a fairly simple data model consisting of two entities:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CurrentLocationId { get; set; }

    public List<Location> Locations { get; set; }
    public Location CurrentLocation { get; set; }
}

and

public class Location
{
    public int Id { get; set; }
    [Required]
    public int UserId { get; set; }
    public string Address { get; set; }

    public User User { get; set; }
}

then in order to get a successful migration to run I needed the following model builder code:

builder.Entity<Location>()
       .HasOne(x => x.User)
       .WithMany(x => x.Locations)
       .HasForeignKey(x => x.UserId);

This has generated a database as I'd expect and how I need it to be. However, I'm unable to save entities due to the following circular dependency error:

InvalidOperationException: Unable to save changes because a circular dependency was detected in the data to be saved: 'ForeignKey: User {'CurrentLocationId'} -> Location {'Id'} ToPrincipal: CurrentLocation, ForeignKey: Location {'UserId'} -> User {'Id'} ToDependent: Locations ToPrincipal: User'.

Is there a way around this in EF Core 2.0?

I have a few options to circumnavigate it by changing my data model, but this is the preferred approach as I can use DB constraints to ensure that all Locations link back to a User, and that every user must have a CurrentLocation set. I know it would solve the issue but I can't really allow nulls on the CurrentLocation field!

The code I'm using to try and store users is as follows (simplified for demo purposes):

var location = new Location
{
    Address = "Some address"
};

_context.Locations.Add(location);

var user = new User
{
    Name = "Stu"
};

_context.Users.Add(user);

user.Locations = new List<Location>
{
    location
};

user.CurrentLocation = location;

await _context.SaveChangesAsync();

and I've also tried

var location = new Location
{
    Address = "Some address"
};

var user = new User
{
    Name = "Stu",
    Locations = new List<Location>
    {
        location
    },
    CurrentLocation = location
};

_context.Users.Add(user);    
await _context.SaveChangesAsync();

But the error remains the same. Can this be fixed by some kind of fancy ModelBuilder overrides? Or am I restricted to changing my data model / allowing nulls where I shouldn't really be allowing nulls?

Thanks in advance!

like image 467
Stu Ratcliffe Avatar asked Nov 15 '17 13:11

Stu Ratcliffe


1 Answers

To answer my own question - just checked and SQL server doesn't support deferrable constraints, so nothing EF can do anyway! Change to the data model it is.

like image 59
Stu Ratcliffe Avatar answered Nov 15 '22 09:11

Stu Ratcliffe