2013-11-30 4 views
7

Предположим, у меня есть несколько стран, каждый из которых имеет ряд городов. Я могу представить это, используя следующие модели:AddOrUpdate EntityFramework приводит к неправильному обновлению внешнего ключа

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 правильно идентифицирует внешние ключи и генерирует таблицы.

Однако, если сейчас я пытаюсь посеять некоторые тестовые данные:

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(); 
     } 
    } 
} 

Первый раз это выполняется, все прекрасно, а поле CountryId в базе данных установлено правильно. Однако, когда я запускаю его во второй раз, db.SaveChanges() пытается установить CountryId of Paris равным 0, что нарушает ограничение, исключающее недействительные внешние ключи.

Проблема заключается в том, что, несмотря на то, что, несмотря на то, что city и country являются проксими для отслеживания изменений, свойство CountryId никогда не обновляется. Однако обновление вручную не помогает.

Является ли это предполагаемым поведением, и если да, то как я могу использовать AddOrUpdate без изменения? Выполнение всего, задавая внешние ключи, похоже, не является вариантом, поскольку они недоступны при первом запуске кода.

ответ

1

AFAIK AddOrUpdate не поддерживает навигационные свойства. Также, когда AddOrUpdate не получает никакого свойства по его вводу, он сохранит его со значением свойства по умолчанию.

В своем стремлении вы используете свойство навигации.

city.Name = "Paris"; 
city.Country = country; 

Но AddOrUpdate не назначает city.CountryId=country.Id внутренне из-за отсутствия поддержки навигации собственности. Таким образом, ваше значение city.CountryId становится 0, которое является значением по умолчанию для int.

Вы должны назначить внешний ключ самостоятельно.

var city = db.Cities.Create(); 
city.Name = "Paris"; 
city.Country = country; 
db.Cities.AddOrUpdate(q => q.Name, city); 

должно быть, как это

var city = db.Cities.Create(); 
city.Name = "Paris"; 
city.Country = country; 
//Assign foreign key by manually. 
city.CountryId = country.Id; 
db.Cities.AddOrUpdate(q => q.Name, city); 

Я не проверял это.

0

Может быть, вам это нужно ...

[Key] 
public virtual int Id { get; set; } 
Смежные вопросы