LINQ to Entities и создание нового экземпляра сущности

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

context.Customers newCustomer = context.Customers.CreateCustomer(...);
newCustomer.FirstName = firstNameTextBox.Text;
newCustomer.Address.Street = streetTextBox.Text;   // this is where the error is thrown

В этот момент я получаю сообщение об ошибке «Ссылка на объект не указывает на экземпляр объекта», поскольку адрес имеет значение null. Первоначально я предполагал, что создание новой сущности клиента автоматически создаст новый экземпляр каждой сущности, с которой она связана, но это не должно быть так. Может ли кто-нибудь привести пример кода того, как это должно работать? Спасибо.


person Community    schedule 04.02.2009    source источник


Ответы (1)


Во-первых, было бы упущением не заметить, что адрес является типом значения; он не имеет личности и не должен быть сущностью. Entity Framework поддерживает такие типы с помощью функции сложных типов. К сожалению, конструктор Entity Framework не поддерживает это (Изменить: исправлено в VS 2010), поэтому единственный способ использовать эту функцию — отредактировать EDMX вручную. Как оказалось, Address — это тип, используемый в большинстве примеров, см., возможно, вы захотите это рассмотреть.

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

Простым решением будет:

newCustomer.Address = new Address()
    {
        Street = streetTextBox.Text,
        // etc.
    };

Однако, поскольку Address на самом деле является типом значения (другими словами, два клиента с одним и тем же уличным адресом, вероятно, должны указывать на один и тот же объект Address), вы можете попытаться выбрать существующий объект Address из контекста, прежде чем просто перейти и новый новый.

newCustomer.Address = (from Addresses in context where ...).FirstOrDefault();
if (newCustomer.Address == null)
{
    newCustomer.Address = new Address()
        {
            Street = streetTextBox.Text,
            // etc.
        };
}
person Craig Stuntz    schedule 04.02.2009
comment
Здесь очень хорош нулевой оператор объединения: custom.Address = (from a in db).FirstOrDefault() ?? new Address { Street = "street" }; - person abatishchev; 16.08.2010