Suppose I have a number of countries, each of which has a number of cities. I can represent this using the following models:
public class Country
{
public virtual int Id { get; set; }
[Required]
public virtual string Name { get; set; }
public virtual ICollection<City> Cities { get; set; }
}
public class City
{
public virtual int Id { get; set; }
[Required]
public virtual string Name { get; set; }
public virtual Country Country { get; set; }
public virtual int CountryId { get; set; }
}
class TestContext : DbContext
{
public DbSet<City> Cities { get; set; }
public DbSet<Country> Countries { get; set; }
}
Entity Framework correctly identifies the foreign keys and generates the tables.
However, if I now try to seed some test data:
static class Program
{
static void Main()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TestContext>());
using (var db = new TestContext())
{
db.Database.Initialize(true);
db.Database.Log = Console.Write;
var country = db.Countries.Create();
country.Name = "France";
db.Countries.AddOrUpdate(a => a.Name, country);
var city = db.Cities.Create();
city.Name = "Paris";
city.Country = country;
db.Cities.AddOrUpdate(q => q.Name, city);
db.SaveChanges();
}
}
}
The first time this is run, all is fine, and the CountryId field in the database is set properly. However, when I run it a second time, db.SaveChanges()
attemps to set the CountryId of Paris to 0, which violates the non-nullable foreign key constraint.
The problem seems to be that despite city
and country
being change-tracking proxies, the CountryId
property is never updating. Updating it manually doesn't help this, though.
Is this the intended behaviour, and if so, how can I use AddOrUpdate
without changing like this? Doing everything by setting foreign keys doesn't seem to be an option, as those aren't available the first time the code runs.