Инициализация сущности POCO с использованием конструктора - PullRequest
2 голосов
/ 11 августа 2011

У меня есть 2 класса POCO:

(выдержка из них):

public class Note
{
    public int Id { get; set; }
    public int CategoryId { get; set; }

    public virtual Category Category { get; set; }

    public Note(int categoryId)
    {
    }
}

public class Category
{
    public int Id { get; set; }

    public virtual ICollection<Note> Notes { get; set; }
}

Это отношение 1:n, Note имеет один Category, и в каждой категории многоNotes.

Я хочу, чтобы конструктор в каждой сущности инициализировал все свойства (это лучше, чем использование Object Initializer).

Но если я использую конструктор в Note,Я не знаю, как «связать» заметку с ее категорией.

Если я передам CategoryId в конструктор, Category будет null.Если я передам Category и назначу идентификатор вручную, Категория будет null.

Итак, есть ли способ, которым я могу инициализировать сущность, используя конструктор, и также получить категорию, связанную с моей заметкой?

EDIT

Как видите, у меня есть конструктор класса Note.Мой вопрос: должен ли я передать categoryId, целый Category предмет?(ReSharper плачет, если я назначаю что-то виртуальному свойству).

Если я передам categoryId объекту, сущности не будут связаны.

Ответы [ 3 ]

12 голосов
/ 12 августа 2011

А какой смысл в ваших усилиях? Это в основном бесполезно, потому что:

  • Вы все еще должны предоставить конструктор без параметров, потому что это нужно EF
  • Ваш пользовательский конструктор никогда не будет использоваться EF
  • Если вы хотите использовать ленивую загрузку, EF нужны свойства навигации virtual
  • Неправильно назначать виртуальные свойства из конструктора, потому что виртуальный код может быть переопределен в производном классе, и ваш конструктор может инициировать выполнение логики в этом производном классе, который еще не был инициализирован (родительский конструктор выполняется первым). В вашем конкретном случае это не проблема, но любой может получить ваш класс и переопределить свойство Category, и это станет проблемой. Это просто неправильная практика.

Инициализаторы - решение всех ваших проблем, так зачем беспокоиться о параметризованном конструкторе? Вы должны определить свои приоритеты. Если вам необходима отложенная загрузка, откажитесь от параметризованного конструктора или согласитесь с тем, что Category должен быть настроен вне конструктора. Если ленивая загрузка не нужна, просто удалите ключевое слово virtual из Category и используйте параметризованный конструктор, как хотите.

0 голосов
/ 11 августа 2011

Если это POCO, предоставьте CategoryId как свойство только для чтения:

public class Note
{
    public int Id { get; set; }
    public int? CategoryId { get { return Category == null ? (int?)null : Category.Id; } }
    public virtual Category Category { get; set; }
}
0 голосов
/ 11 августа 2011

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

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

...