Как мне заставить Entity Framework инициализировать коллекции на моих вновь созданных объектах?

#.net #asp.net-mvc #entity-framework #sql-server-ce #ef-code-first

#.net #asp.net-mvc #entity-framework #sql-server-ce #ef-code-first

Вопрос:

Я пытаюсь заполнить свою базу данных некоторыми тестовыми данными с помощью IDatabaseIntialiser такого:

 protected override void Seed(BlogDataContext context)
{
    // <snip>
    var post = context.Posts.Create();
    post.Title = "My Life On Twitter";
    // <snip properties>

    // Set tags
    post.Tags.Add(aspnetTag); // NullRefException
    post.Tags.Add(razorTag);
  

Объект Post выглядит следующим образом:

 public class Post
{
    // ...
    public virtual ICollection<Tag> Tags { get; set; }
  

Полные объекты в Bitbucket: Post и Tag. Весь код находится в http://code.dantup.com/blog

Однако post.Tags равно null, поэтому это не работает. Изначально я создавал post как new Post() , однако, поскольку я вызываю Create метод, предоставляемый EF, почему коллекция не инициализируется?

Создание моей собственной коллекции здесь кажется неуклюжим, и если я делаю это в конструкторе, предположительно, каждый раз, когда я загружаю объект из EF, он создаст коллекцию в конструкторе, а затем перезапишет ее коллекцией, содержащей фактические данные из базы данных?

Есть ли какой-нибудь способ сообщить EF создать мне объект, включая коллекции / прокси для моего ICollections (предполагая ICollection , что это правильный выбор)?

Для Edit: context.Configuration.ProxyCreationEnabled установлено значение true (по умолчанию), которое, похоже, существует по этой причине?

Комментарии:

1. посмотрите здесь: prodinner.codeplex.com в исходном коде инициализация коллекции не требуется, по крайней мере, с помощью EF4.1 CodeFirst POCOs

2. code.google.com/p/prodinner/source/browse/trunk/Core/Model/…

3. @Omu — Я использую EF4.1, но при создании коллекции имеют значение null, но выглядят так же, как и их собственные

4. можете ли вы показать нам свои объекты?

5.Я опубликовал соответствующую часть, но если вы хотите увидеть полные файлы bitbucket.org/DanTup/dantup-blog/src/03cfceba726b/DanTup Blog /… bitbucket.org/DanTup/dantup-blog/src/03cfceba726b/DanTup Blog/… Весь код находится в code.dantup.com/blog

Ответ №1:

С помощью объектов POCO и EF я обычно инициализирую коллекцию в конструкторе. И я предпочитаю ISet, а не ICollection 😉

Комментарии:

1. Чем вы это инициализируете? Это кажется неуклюжим, поскольку EF будет инициализировать вещи по-другому при загрузке (возможно, с помощью прокси). Я хотел бы знать, можно ли сделать это так же. Также — ISet vs ICollection — Я продолжаю гуглить, но не могу найти никакой информации, какие коллекции лучше всего использовать с EF и по какой причине: (

2. Если я использую ISet<T> , я создам экземпляр HasSet<T> . Я полагаю, EF достаточно умен, чтобы проверить, что коллекция была инициализирована, когда он пытается связать ее с вашими объектами. Набор гарантирует, что каждый элемент в его коллекции уникален. Коллекция допускает многократную ссылку на один и тот же объект.

3. Если вы посмотрите на свое исходное представление вашей ICollection после извлечения его из вашего DbContext, вы можете увидеть, что EF будет использовать HashSet<T> для инициализации ваших объектов. Я бы предложил сделать то же самое в вашем свойстве get / set. Тем не менее — я согласен, что это неудовлетворительно. MVC создает объекты за вас, поэтому вам придется испортить код вашей модели инициализацией, специфичной для EF. Я бы предпочел, чтобы это поведение контролировалось с помощью атрибутов. Однако, если вы используете new () для создания экземпляров своих объектов, то EF не сможет узнать о них, пока вы не поместите их в свой ObjectContext.