2015-08-12 4 views
0

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

Я использую первый подход кода. Вот соответствующий код для Адреса:

public class Address 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    [ForeignKey("ID")] 
    public virtual Visit Visit { get; set; } 

и для посещений:

public class Visit 
    { 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    [ForeignKey("ID")] 
    public virtual Address Address { get; set; } 

На основе моих исследований, я также должен был включать в себя следующее в методе OnModelCreating моего DataContext в:

modelBuilder.Entity<Visit>() 
     .HasOptional(v => v.Address) 
     .WithRequired(); 

К сожалению, это не работает. Я могу обновить базу данных в порядке, после устранения вызовов на строительные леса, чтобы удалить основной индекс из Адресов (вероятно, потому, что код добавления-миграции считает, что первичный ключ является «просто» полем внешнего ключа). Но когда я запускаю приложение, я получаю следующее сообщение об ошибке:

Invalid column name 'Address_ID'. Invalid column name 'Address_ID'.

Из моего ограниченного опыта с EF6 это выглядит где-то глубоко внутри рамки он ожидает там быть поля с именем «Address_ID», вероятно, в таблице посещения (основанный на структуре имен именования «имя таблицы» _ «имя поля», которую я видел для других неявно добавленных полей).

Является ли то, что я пытаюсь сделать возможным? Если да, то что мне не хватает в конфигурации?

Дополнительная информация

В пробуя предложенное решение Буби, которая, к сожалению, до сих пор порождает ту же ошибку, что я мог бы устранить код OnModelCreating и все еще получить функциональный код миграции генерируется.

Разрешение

я, наконец, сделал то, что должен был сделать раньше, что изучение фактического кода T-SQL, сгенерированный запросом, который дует вверх. Оказывается, проблема не в связи с визитом/адресом, а в совершенно разных отношениях, связанных с другой таблицей. По-видимому, где-то по пути я делал что-то, чтобы заставить EF думать, что другая таблица (Избиратели) имеет поле внешнего ключа Address_ID. На самом деле отношения Address/Voter должны были быть и были первоначально привязаны к полю Voter.AddressID.

Вместо того, чтобы пытаться раскрутить большое количество миграций, я решил сдуть базу данных, сдуть миграцию и начать с нуля. После воссоздания базы данных - но с помощью предложения bubi - я перезагрузил данные из резервной копии и, вуаля, вернулся в бизнес.

Для полноты картины, вот код, который я закончил тем, что положить в вызове метода OnModelCreating, чтобы получить адрес/посещение отношения для правильной работы:

modelBuilder.Entity<Visit>() 
    .HasRequired(v => v.Address) 
    .WithRequiredDependent(a => a.Visit); 

modelBuilder.Entity<Address>() 
    .HasRequired(a => a.Visit) 
    .WithRequiredPrincipal(v => v.Address); 

Я немного запутался о том, почему я должны использовать HasRequired, чтобы иметь возможность использовать WithRequiredPrincipal/WithRequiredDependent, поскольку не каждая запись в таблице Address имеет запись в таблице Visit. Это кажется «факультативным», а не «обязательным». Но, похоже, это работает, и, возможно, «требуемая» часть просто внутренняя к модели базы данных EF, а не к самой базе данных.

ответ

1

В модели есть 2 проблемы:
- Только один из Ключей может быть пронумерован, другой должен получить тот же ИД (это независимо от EF).
- Проблема с отображением.
Эта модель должна работать.

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

    public string Description { get; set; } 

    public virtual Visit Visit { get; set; } 
} 

public class Visit 
{ 
    public Visit() 
    { 
     Address = new Address(); 
    } 

    [Key] 
    [ForeignKey("Address")] 
    public int Id { get; set; } 

    public string Description { get; set; } 

    public virtual Address Address { get; set; } 
} 

Пример использования

  var visit = new Visit 
      { 
       Description = "Visit", 
       Address = {Description = "AddressDescription"} 
      }; 

      db.Visits.Add(visit); 

      db.SaveChanges(); 
+0

Спасибо за ответ, но это не сработало. Такая же ошибка времени выполнения все еще сгенерирована (жалоба о невозможности найти столбец с меткой «Address_ID», который EF, по-видимому, ищет в таблице Visites. Я обновил свой вопрос, чтобы включить дополнительную информацию о вызовах modelBuilder. –

+0

I отправил код после запуска. Попробуйте отбросить базу данных и снова запустить код. – bubi

1

В дополнение к тому, что Буби упоминалось, ваше modelBuilder заявление противоречит модели в том, что он не упоминает Address.Visit в качестве обратного свойства. Поэтому он считает, что свойство представляет собой отдельную взаимосвязь и пытается создать столбец Address_ID для этой связи.

Вы должны иметь

modelBuilder.Entity<Visit>() 

    // from your description sounds like every Visit needs an Address 
    .HasRequired(v => v.Address) 

    // need to mention the inverse property here if you have one 
    .WithOptional(a => a.Visit); 

... или просто удалить заявление полностью, так как вы уже используете атрибуты и EF должны быть в состоянии понять это по соглашению.