#.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.