нужны рекомендации по созданию / обновлению связанных объектов (возможно ли это с помощью automapper?)

#c# #asp.net #asp.net-mvc #entity-framework #automapper

#c# #asp.net #asp.net-mvc #entity-framework #automapper

Вопрос:

Я новичок в ASP.NET MVC и хотел бы улучшить здесь. Я использовал ASP.NET Первый подход к кодированию MVC EF. Но я немного запутался в том, как создавать / обновлять связанные объекты. Итак, вот мой сценарий. Скажем,

 public class Item
{
  public int Id { get; set; }
  public string Name { get; set; }

  public virtual ICollection<Stock> Stocks { get; set; }
}

public class Stock
{
  public int Id { get; set; }
  public int ItemId { get; set; }
  public int StorageId { get; set; }
  public float Amount { get; set; }

  public virtual Item Item { get; set; }
  public virtual Storage Storage { get; set; }
}

public class Storage
{
  public int Id { get; set; }
  public Name { get; set; }

  public virtual ICollection<Stock> Stocks { get; set; }
}
  

Таким образом, an Item имеет отношение 1: многие Stock . И Storage имеет отношение 1: many с Stock

При их отображении я использовал Automapper , который работал отлично. (Спасибо SO за помощь мне)

Теперь, чего я пытаюсь достичь, так это.. Как создавать / обновлять объекты? (Возможно ли использовать Automapper здесь?)

Скажем, в одном POST он добавит Item , с Stock и с выбранным Storage . Пример кода был бы отличным для справки.

Любая помощь будет высоко оценена. Спасибо

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

1. Вы пытались использовать свой DbContext?

2. Да, это так. На самом деле он выполнил INSERT оператор, но только для корневого объекта. Думаете, есть способ также добавить связанные объекты в корневой объект?

Ответ №1:

AutoMapper — это всего лишь инструмент для сопоставления свойств View Model вашего / вашего Domain Model .

Это то View Model , что вы используете во всех своих представлениях, а ваша модель домена является базовой бизнес-моделью, которая не должна быть доступна представлениям.

Это то, что упрощает AutoMapper, он отображает свойства этих двух моделей, так что нам не нужно продолжать преобразовывать одну модель в другую.


Теперь переходим к созданию / обновлению связанных объектов…

Скажем, мы хотим добавить новое Stock , используя свойство навигации на Item .

 Item item = this.DbSource.Items.First(itemEntity => itemEntity.Id == 5);

if(item.Stocks == null) item.Stocks = new Collection<Stock>();

item.Stocks.Add(new Stock
{
    StorageId = 3,
    Amount = 123F
});

this.DbSource.SaveChanges();
  

Другим случаем, на который вы только что указали, было наличие нового Item и X-го количества Stock того Item , что вы хотите сохранить в базе данных за одну операцию.

 Storage storage = this.DbSource.Storages.First(storageEntity => storageEntity.Id == 3);

if(storage.Stocks == null) storage.Stocks = new Collection<Stock>();

Stock stock = new Stock
{
    StorageId = 3,
    Amount = 123F,
    Item = new Item
    {
        Name = "Redbull"
    }
};

storage.Stocks.Add(stock);

this.DbSource.SaveChanges();
  

Или если у вас нет данных в вашей базе данных, и вы хотите, чтобы все 3 модели были опубликованы за один раз…

 Stock stock = new Stock
{
    Amount = 123F,
    Item = new Item
    {
        Name = "Redbull"
    }
};

Storage storage = new Storage
{
    Name = "It's a secret"
};

storage.Stocks.Add(stock);

this.DbSource.Storages.Add(storage);

this.DbSource.SaveChanges();
  

Также измените все ваши модели с помощью конструктора, который инициализирует a Collection для всех ваших ICollection навигационных свойств, таким образом, вы можете избежать NullReferenceException

Так, например, измените Item класс на этот

 public class Item
{
    public Item()
    {
        this.Stocks = new Collection<Stock>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Stock> Stocks { get; set; }
}
  

Использование элемента в качестве корневого свойства

 Collection<Stock> stocks = new Collection<Stock>();
Collection<Stock> stocks.Add(new Stock 
{
    StorageId = 123,
    Amount = 1000F
}); 

Item item = new Item
{
    Name = "Pizza",
    Stocks = stocks
}; 

this.DbSource.SaveChanges();
  

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

1. ДА. Этот способ будет работать. Но что, если вы добавите Item и Stock все сразу в один POST . Думаете, есть способ? Кстати, спасибо за объяснение Automapper .

2. Конечно. Большое вам спасибо.

3. Что, если корневой объект есть Item . Будет ли применяться та же идея?

4. Спасибо, чувак. Это действительно работает. Но как-то переполнено Controller . Во всяком случае, теперь я могу двигаться дальше. Спасибо, приятель.

5. Вот где AutoMapper приходит… у вас будет ViewModel для вашего Form , а внутри AutoMapper вы сопоставите свойства… Вы можете найти их документацию здесь , проверьте ее, она действительно хорошо написана.