2012-06-27 3 views
8

При использовании Entity Framework Code First 4.3.1 можно создавать отношения с кратностью 1-к-1. То есть, одна сущность на каждом конце отношений.Entity Framework Code First One-к-одному Required-Required Relationship

Можно настроить 1-на-1 отношения быть требуется, требуется или требуется факультативные ^. Однако, когда я переключаюсь между этими двумя, я не вижу различий в:

  • Созданная схема базы данных. Я нацелен на SQL Server 2008.
  • Среда выполнения EF.

Таким образом, я могу создать RequiredPrincipalAs запись без соответствующего RequiredDependentAs записи, несмотря на отношения быть сконфигурированы как требуется, требуется. Это, кажется, противоречит документации по HasRequired (...):

конфигурирует необходимую связь от этого типа объекта. Экземпляры типа сущности не могут быть сохранены в базе данных, если это отношение не указано. Внешний ключ в базе данных будет недействительным.

http://msdn.microsoft.com/en-us/library/gg671317

В требуемых- требуется отношения лиц:

public class RequiredPrincipalA 
{ 
    public int Id { get; set; } 
    public virtual RequiredDependentA DependentA { get; set; } 
} 

public class RequiredDependentA 
{ 
    public int Id { get; set; } 
    public virtual RequiredPrincipalA PrincipalA { get; set; } 
} 

В требуемых факультативных отношений лица:

public class RequiredPrincipalB 
{ 
    public int Id { get; set; } 
    public virtual OptionalDependentB DependentB { get; set; } 
} 

public class OptionalDependentB 
{ 
    public int Id { get; set; } 
    public virtual RequiredPrincipalB PrincipalB { get; set; } 
} 

DbContext и модель конф iguration:

public class AppContext : DbContext 
{ 
    public DbSet<RequiredPrincipalA> PrincipalAs { get; set; } 
    public DbSet<RequiredDependentA> DependentAs { get; set; } 

    public DbSet<RequiredPrincipalB> PrincipalBs { get; set; } 
    public DbSet<OptionalDependentB> DependentBs { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<RequiredPrincipalA>() 
      .HasRequired(o => o.DependentA) 
      .WithRequiredPrincipal(o => o.PrincipalA); 

     modelBuilder.Entity<RequiredPrincipalB>() 
      .HasOptional(o => o.DependentB) 
      .WithRequired(o => o.PrincipalB); 
    } 
} 

Тест Код:

Database.SetInitializer(new DropCreateDatabaseAlways<AppContext>()); 

using (var ctx = new AppContext()) 
{ 
    ctx.Database.Initialize(force: false); 

    ctx.PrincipalAs.Add(new RequiredPrincipalA()); 
    ctx.PrincipalBs.Add(new RequiredPrincipalB()); 

    ctx.SaveChanges(); 
} 

Я знаю, я мог бы добавить атрибут данных [обязательно] для навигационных свойств RequiredPrincipalA.DependentA и RequiredDependentA.PrincipalA , Это приведет к тому, что проверка EF позволит предотвратить описанный выше сценарий. Однако я не хочу этого делать, потому что он также проверяет, что свойство навигации заполняется при обновлении существующего объекта. Это означает, что приложение должно предварительно получить объект на другом конце отношения для каждого обновления.

Почему я не вижу никакой разницы в поведении EF только при изменении отношения между требуется, требуется и требуется факультативные?

^Обратите внимание, что по желанию факультативные также поддерживается, но это не является частью моего вопроса. Существуют очевидные различия в сгенерированной схеме базы данных и времени выполнения, когда настраивается необязательно-необязательное отношение.

ответ

13

Я не знаю, почему требуемый-необходимый разрешен для этого случая, но он не может существовать в базе данных, потому что отношение построено на первичных ключах. Обязательный параметр означает, что A не может быть вставлен, если связанный B не существует, и B не может быть вставлен, если родственный A не существует => ни A, ни B не могут быть вставлены.

Отношение базы данных всегда имеет основную и зависимую сущность - принцип всегда может существовать без зависимости.

Реальный требуемый в EF-режиме может быть достигнут только тогда, когда оба A и B отображаются в одну и ту же таблицу (table splitting), потому что в этом случае они оба вставлены с одной командой вставки.

+0

Благодарим вас за ответ. Это, безусловно, уточняет аспект схемы базы данных моего вопроса. Тем не менее, я очень хочу понять, почему в EF нет каких-либо явных поведенческих изменений. –

+0

Возможно ли, что требуемое-необходимое разрешено, поскольку оно может быть исполнено EF, даже если на самом деле это невозможно для принудительного применения этого ограничения в SQL? –

+0

Люк, факт отсутствия различий в схеме при настройке r/r и r/o теперь понимается благодаря ответу Ладислава. Теперь дело в том, что r/r, похоже, не работает во время исполнения EF, несмотря на то, что заявляет документация. –

5

Не совсем ответ, но мне нужно сказать больше, чем в комментариях. Но вы знаете, я пишу 900 страниц книг ... это как раз то, как я рулон. :)

Как ни странно, я бы ожидал, что плавная конфигурация будет вести себя так же, как аннотация данных, и я смущен, что он этого не делает. (Я пинговал Rowan Miller со ссылкой на эту тему, чтобы получить его отзыв.) И я имею в виду следующее: проверка ограничения во время SaveChanges.

На стороне базы данных я с Ladislav. В модели EF определяет 1: 1, используя ключи связанных объектов. Но в базе данных вы не можете иметь FK в обеих таблицах, поэтому только зависимая таблица в базе данных будет требовать, чтобы ограничение, которое PK сопоставляет с существующей PK в главной таблице.

И, наконец, я понимаю, что вы не хотите, чтобы EF обеспечивал соблюдение отношений, если вы не собираетесь всегда иметь дело с полным графиком. Я думаю, что отношения 1: 1 являются наиболее запутанными для сопоставлений отношений EF, и мне всегда приходится возвращаться для напоминаний о правилах и о том, как все должно работать.

Смежные вопросы