EF Code Во-первых, создайте новый объект в коллекции с прокси - PullRequest
0 голосов
/ 20 августа 2011

Как я могу создать + persist + have-a-proxy-to новый экземпляр poco с первым кодом, используя только наборы свойств навигации? В приведенном ниже коде я покажу, как вы можете это сделать, если используете функции-члены для создания POCO, которые затем создают POCO. У вас нет DbContext, но если вы создаете объект и сохраняете его с помощью DbSet.Add, возвращаемый объект не является прокси, поэтому вы не можете, в свою очередь, использовать его DbSet.Add для добавления другого подобъекта. .

В этом коде, если вы вызываете MailingList.AddIncomingMessage («мое сообщение»), вы получаете исключение в комментарии «OOPS», потому что созданное сообщение не является прокси-сервером и, следовательно, его свойство Message.doodads имеет значение null.

class Doodad {
  public int ID { get; set; }
  public string doodad { get; set; };
}

class Message {
  public int ID { get; set; }
  public virtual MailingList mailingList { get; set; } 
  public virtual ICollection<Doodad> doodads { get; set; }
  public string text { get; set; }

  public void GetDoodadCreateIfNeeded(string doodad) {
    try {
      // won't be found since we just created this Message
      return this.doodads.First(d => d.doodad == doodad);
    } catch (Exception e) {
      Doodad newDoodad = new Doodad() { doodad=doodad };

      // OOPS! this.doodads == null, because its not a proxy object
      this.doodads.Add(newDoodad);
      return newDoodad;
    }
  }
}

class MailingList {
  public int ID { get; set; }
  public virtual ICollection<Message> messages { get; set; }

  public void AddIncomingMessage(string message) {
    var msg = new Message() { text=message };

    // we have no Context, because we're in a POCO's member function
    this.messages.Add(msg);

    var doodad = msg.GetDoodadCreateIfNeeded("bongo drums");
  }
}

РЕДАКТИРОВАТЬ: извините, ребята, я забыл вставить аксессоры свойств и ID для этого упрощенного случая, но я использую их в фактическом коде.

Ответы [ 2 ]

2 голосов
/ 20 августа 2011

Это не имеет ничего общего с прокси.Он такой же, как и любой другой код - если вы хотите использовать объект / коллекцию, вы должны сначала его инициализировать!Ваша первая команда:

return this.doodads.First(d => d.doodad == doodad);

не выдает исключение, потому что не нашла doodad, а потому что doodads имеет значение null.

Что вам нужно сделать?Вам нужно инициализировать коллекции перед первым использованием.Вы можете сделать это:

  • Непосредственно в их определении
  • В конструкторе сущности
  • В получателе свойств (отложенная инициализация), как только они в первый раз нужны - для этого потребуетсяизмените ваши поля на свойства, что кстати.правильный способ написания классов в .NET
  • В ваших пользовательских методах вы можете проверить, являются ли они нулевыми, и инициализировать их
1 голос
/ 20 августа 2011

В дополнение к свойству навигации у вас должно быть свойство, которое является идентификатором внешнего ключа.

Таким образом, ваш MailingList должен иметь это свойство:

  [Key] // this attribute is important
  public int Id { get; set; }

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

public virtual int mailingListId { get; set; 
public virtual MailingList mailingList { get; set; }

Свойство { get; set; } важно, так что это свойство, а не просто открытый атрибут.

...