Entity Framework сохраняет данные в связях один к одному

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

Вот так выглядят модели:

public class Team
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int OwnerID { get; set; }
    public virtual User Owner { get; set; }
}

public class User
{
    public int ID { get; set; }
    public string UserName { get; set; }

    public int TeamID { get; set; }
    public virtual Team Team { get; set; }
}

Я добавил эти биты в DbContext OnModelCreating(), как указано в сообщении в блоге, указанном выше:

modelBuilder.Entity<User>()
    .HasRequired(u => u.Team)
    .WithMany()
    .HasForeignKey(u => u.TeamID);

modelBuilder.Entity<Team>()
    .HasRequired(t => t.Owner)
    .WithMany()
    .HasForeignKey(t => t.OwnerID)
    .WillCascadeOnDelete(false);

А теперь при добавлении данных вот так:

User u = new User();
u.UserName = "farinha";
Team t = new Team("Flour Power");
u.Team = t;
t.Owner = u;
context.Users.Add(u);
context.Teams.Add(t);
context.SaveChanges();

или даже так:

User u = new User();
u.UserName = "farinha";
u.Team = new Team("Flour Power");
context.Users.Add(u);
context.SaveChanges();

Я получаю следующую ошибку:

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

Есть идеи, как это решить? Я неправильно сохраняю данные?

заранее спасибо


person Farinha    schedule 10.05.2011    source источник


Ответы (1)


Вы не сохраняете данные неправильно, но они просто не могут работать, потому что вы определили двунаправленную зависимость. Команда может быть сохранена, только если связана с уже сохраненным пользователем, а пользователь может быть сохранен, только если связан с существующей командой. Вы должны сделать одно отношение необязательным, пометив свойство внешнего ключа как обнуляемое (например, TeamId в User):

public class User
{
    public int ID { get; set; }
    public string UserName { get; set; }

    public int? TeamID { get; set; }
    public virtual Team Team { get; set; }
}

Затем вы должны сначала сохранить объект User, а затем вы можете сохранить Team.

User u = new User();
u.UserName = "farinha";
context.Users.Add(u);
context.SaveChanges();

u.Team = new Team { Name = "Flour Power", OwnerID = u.ID };
context.SaveChanges();
person Ladislav Mrnka    schedule 10.05.2011
comment
@ladislav-mrnka Это приводит к тому, что ошибка меняется на Cannot insert the value NULL into column 'TeamID', table 'DeuceHigh.dbo.User'; column does not allow nulls. INSERT fails. The statement has been terminated. - person Farinha; 11.05.2011
comment
@Farinha Поскольку ваша модель изменилась, ваша таблица базы данных тоже обновилась? - person DDiVita; 11.05.2011
comment
@Farinha: это ошибка уровня базы данных, что означает, что TeamID в таблице пользователей по-прежнему не может быть обнулен. Вы не воссоздавали и не модифицировали базу данных. - person Ladislav Mrnka; 11.05.2011
comment
Я настроил EF для удаления и воссоздания базы данных при изменении модели, поэтому БД воссоздается, что должно привести к тому, что TeamID будет создано как обнуляемое. Бит в DbContext OnModelCreating() мог вызывать проблемы, поэтому я изменил объект User на HasOptional(u => u.Team), который теперь вызывает конфликт оператора INSERT с ограничением FOREIGN KEY Team_Owner. Конфликт произошел в базе данных DeuceHigh, таблица dbo.User, столбец "ID" - person Farinha; 11.05.2011
comment
Я отредактировал свой ответ. Вы должны вручную установить OwnerID в новой команде, потому что ваши два отношения не зависят друг от друга. - person Ladislav Mrnka; 11.05.2011
comment
Это выглядит прямо сейчас, но также пришлось изменить бит в DbContext OnModelCreating(), о котором я упоминал в своем комментарии выше. Кажется, это то, что фактически приводит к тому, что столбец БД может быть нулевым. - person Farinha; 11.05.2011