Поделиться через


Сохранение связанных данных

Помимо изолированных сущностей, можно также использовать связи, определенные в модели.

Подсказка

Вы можете скачать используемый в этой статье пример из репозитория GitHub.

Добавление графа новых сущностей

Если вы создаете несколько связанных сущностей, добавление одного из них в контекст приведет к тому, что другие также будут добавлены.

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

using (var context = new BloggingContext())
{
    var blog = new Blog
    {
        Url = "http://blogs.msdn.com/dotnet",
        Posts = new List<Post>
        {
            new Post { Title = "Intro to C#" },
            new Post { Title = "Intro to VB.NET" },
            new Post { Title = "Intro to F#" }
        }
    };

    context.Blogs.Add(blog);
    await context.SaveChangesAsync();
}

Подсказка

Используйте свойство EntityEntry.State, чтобы задать состояние только одной сущности. Например: context.Entry(blog).State = EntityState.Modified.

Если вы ссылаетесь на новую сущность из навигационного свойства той сущности, которая уже отслеживается контекстом, эта сущность будет обнаружена и добавлена в базу данных.

В следующем примере сущность post вставляется, так как она добавлена в свойство Posts сущности blog, которая была извлечена из базы данных.

using (var context = new BloggingContext())
{
    var blog = await context.Blogs.Include(b => b.Posts).FirstAsync();
    var post = new Post { Title = "Intro to EF Core" };

    blog.Posts.Add(post);
    await context.SaveChangesAsync();
}

Изменение связей

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

В следующем примере сущность post обновляется, чтобы она принадлежала новой сущности blog, так как свойство Blog навигации указывает на blog. Обратите внимание, что blog также будет вставлен в базу данных, так как он является новой сущностью, на которую ссылается свойство навигации сущности, которая уже отслеживается контекстом (post).

using (var context = new BloggingContext())
{
    var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
    var post = await context.Posts.FirstAsync();

    post.Blog = blog;
    await context.SaveChangesAsync();
}

Удаление связей

Вы можете удалить связь, установив навигационную ссылку на null, или удалив связанную сущность из навигации по коллекции.

Удаление связи может иметь побочные последствия для зависимой сущности в соответствии с поведением каскадного удаления, настроенным в связи.

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

Ознакомьтесь с разделом "Обязательные и необязательные связи" , чтобы узнать, как можно настроить необходимые отношения.

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

В следующем примере каскадное удаление настраивается для связи между Blog и Post, таким образом сущность post удаляется из базы данных.

using (var context = new BloggingContext())
{
    var blog = await context.Blogs.Include(b => b.Posts).FirstAsync();
    var post = blog.Posts.First();

    blog.Posts.Remove(post);
    await context.SaveChangesAsync();
}