Entity Framework 6: добавление дочернего объекта в родительский список и установка дочернего свойства навигации родительскому объекту

У меня есть существующая база данных с двумя таблицами MailServers и MailDomains. MailDomains имеет столбец внешнего ключа MailServerId, указывающий на столбец первичного ключа Id в MailServers. Таким образом, у нас есть отношения "один-ко-многим".

Я следил за в этой статье и создал мои POCO Framework Entity Framework с помощью модели "Код сначала из базы данных" в Мастере моделей данных сущностей. Это привело к следующим двум классам С#:

public partial class MailServer
{
    public MailServer()
    {
        MailDomains = new HashSet<MailDomain>();
    }

    public int Id { get; set; }

    public virtual ICollection<MailDomain> MailDomains { get; set; }
}



public partial class MailDomain
{
    public MailDomain()
    {
    }

    public int Id { get; set; }

    public string DomainName { get; set; }

    public int MailServerId { get; set; }
    public virtual MailServer MailServer { get; set; }
}

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

Подход (A): добавление нового дочернего элемента в родительский список:

        var mailServer = new MailServer();
        var mailDomain = new MailDomain() {
            DomainName = "foobar.net",
        };
        mailServer.MailDomains.Add(mailDomain);

        using(var context = new MyContext){
            context.MailServers.Add(mailServer);
            context.SaveChanges();
        }

Подход (B): настройка родительского свойства дочерней навигации:

        var mailServer = new MailServer();
        var mailDomain = new MailDomain() {
            DomainName = "foobar.net",
            MailServer = mailServer,
        };

        using(var context = new MyContext){
            context.MailDomains.Add(mailDomain);
            context.SaveChanges();
        }

Я также предполагаю, что в подходе (A) новый экземпляр MailDomain автоматически добавляется в коллекцию context.MailDomains, а в подходе (B) новый экземпляр MailServer автоматически добавляется в коллекцию context.MailServers. Это правильно или мне нужно сделать это вручную?

Итак, опять мой вопрос: оба подхода взаимозаменяемы? Меня просто смущает то, что в базе данных есть только одно свойство/столбец для установки (а именно, внешний ключ в MailDomains), тогда как в коде С# есть два свойства (по одному в каждом классе), которые могут быть изменены.

Ответ 1

Да, оба подхода взаимозаменяемы. Это позволяет создавать и сохранять граф объектов в базе данных с точки зрения MailServer или MailDomain.

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

Я также предполагаю, что в подходе (A) новый экземпляр MailDomain автоматически добавляется в context.MailDomains в то время как в подходе (B) новый экземпляр MailServer автоматически добавляется в context.MailServers. Это правильно или мне нужно сделать это вручную?

Это зависит от того, что вы подразумеваете под "добавлением в контекст". Если вы имеете в виду: автоматически ли он будет сохранен в базе данных, когда вы будете продолжать, ответ будет да. Одним из больших преимуществ использования ORM, такого как EF, является то, что он автоматически сохраняет полный граф объектов (и синхронизирует отношения PK/FK и т.д.).

Если вы имеете в виду: будет ли объект доступен через контекст перед сохранением, я так не думаю (я не уверен на 100%).