none
Добавление кастомной модели в базу данных RRS feed

  • Вопрос

  • Здравствуйте. У меня вопрос, связанный с построением архитектуры приложения.

    Есть три базы данных, 1- группы, 2 - дни(7 дней недели) и 3-расписание, где отражена связь "многие ко многим" двух предыдущих таблиц, т.е. несколько групп могут заниматься в один и тот же день и одна группа может заниматься в разные дни недели.

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

    класс модели:

    public class ScheduleViewModel
        {
                public int GroupId { get; set; }
                public string GroupName { get; set; }
                public string MondayTime { get; set; }
                public string TuesdayTime { get; set; }
                public string WednesdayTime { get; set; }
                public string ThursdayTime { get; set; }
                public string FridayTime { get; set; }
                public string SaturdayTime { get; set; }
                public string SundayTime { get; set; }
        }

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

    db.Entry().State = EntityState.Modified;
                db.SaveChanges();

    Подскажите пожалуйста, как можно решить эту проблему?

    4 октября 2012 г. 13:12

Ответы

  • Да, в действительности в большинстве случаев без  DTO не обойтись, что Вы и делаете. "Все отлично с помощью моей модели я могу вывести данные, но я не могу сделать так, что бы с этой же моделью я работал для того что бы изменить таблицы в базе данных, т.е. я не могу понять, как заставить мое представление типа Edit представление(вьюху если удобнее) заменить данные в базе данных на те которые ввел пользователь." - вам нужны сервисные классы (обычно они помещаются в репозиторий) методы которых и будут разбирать объекты DTO и выполнять логику связанную с объявлением. В общем схема такая: контроллер получает данные в виде DTO объекта (Ваш ScheduleViewModel) вызывает метод репозитория (слоя доступа к данным) передав ему данный объект, то разбирает его и делает своё дело, обновляет данные.
    • Предложено в качестве ответа YatajgaEditor 10 октября 2012 г. 5:44
    • Помечено в качестве ответа Abolmasov Dmitry 12 октября 2012 г. 12:49
    • Снята пометка об ответе akavoid 15 октября 2012 г. 13:44
    • Помечено в качестве ответа akavoid 16 октября 2012 г. 18:42
    6 октября 2012 г. 19:20
    Модератор
  • спасибо вам я сам додумался.

    В общем надо было сделать так:

    хранить idшники во вьюхе с помощью вот таких записей

    @Html.HiddenFor(model => model.MondayTimeID);
            @Html.HiddenFor(model => model.TuesdayTimeID);
            @Html.HiddenFor(model => model.WednesdayTimeID);
            @Html.HiddenFor(model => model.ThursdayTimeID);
            @Html.HiddenFor(model => model.FridayTimeID);
            @Html.HiddenFor(model => model.SaturdayTimeID);
            @Html.HiddenFor(model => model.SundayTimeID);

    и собственно добавить эти поля в модель

    public class ScheduleViewModel
        {
                public int GroupId { get; set; }
                public string GroupName { get; set; }
                public string MondayTime { get; set; }
                public string TuesdayTime { get; set; }
                public string WednesdayTime { get; set; }
                public string ThursdayTime { get; set; }
                public string FridayTime { get; set; }
                public string SaturdayTime { get; set; }
                public string SundayTime { get; set; }

                public int MondayTimeID { get; set; }
                public int TuesdayTimeID { get; set; }
                public int WednesdayTimeID { get; set; }
                public int ThursdayTimeID { get; set; }
                public int FridayTimeID { get; set; }
                public int SaturdayTimeID { get; set; }
                public int SundayTimeID { get; set; }
        }

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

    • Помечено в качестве ответа akavoid 16 октября 2012 г. 18:42
    16 октября 2012 г. 18:42

Все ответы

  • Наверное Вы имели ввиду таблицы. Можете привести код сущностных классов, и постарайтесь описать более точно, что требуется, пока не очень понял.
    4 октября 2012 г. 14:06
    Модератор
  • Спасибо, что всегда пытаетесь мне помочь.

    В общем такая ситуация, у меня есть три таблицы:

    public class Days
        {
            public Days()
            {
                Schedule = new List<Schedules>();
            }
            [Key]
            public int Id { get; set; }
            [Required(ErrorMessage="Название дня - обязательное поле")]
            public string Name { get; set; }
            public virtual ICollection<Schedules> Schedule { get; set; }
        }
    
    public Groups()
            {
                Schedule = new List<Schedules>();
            }
            [Key]
            public int Id { get; set; }
            [Required(ErrorMessage="Название группы - обязательное поле")]
            [Display(Name = "Название группы")]
            public string Name { get; set; }
            [Display(Name = "Описание")]
            [DataType(DataType.Html)]
            public string Description { get; set; }
            public virtual ICollection<Schedules> Schedule { get; set; }
        }
    
    public class Schedules
        {
            [Key]
            public int Id { get; set; }
            public int DayId { get; set; }
            public int GroupId { get; set; }
            [Display(Name="Время занятий")]
            public string Time { get; set; }
            public virtual Groups Group { get; set; }
            public virtual Days Day { get; set; }
    
        }


    Для того что бы с ними было удобно работать я создал модель итоговой таблицы(точнее одной ее записи)

    Которая будет отображаться на моем представлении.

    public class ScheduleViewModel
        {
                public int GroupId { get; set; }
                public string GroupName { get; set; }
                public string MondayTime { get; set; }
                public string TuesdayTime { get; set; }
                public string WednesdayTime { get; set; }
                public string ThursdayTime { get; set; }
                public string FridayTime { get; set; }
                public string SaturdayTime { get; set; }
                public string SundayTime { get; set; }
        }

    Все отлично с помощью моей модели я могу вывести данные, но я не могу сделать так, что бы с этой же моделью я работал для того что бы изменить таблицы в базе данных, т.е. я не могу понять, как заставить мое представление типа Edit представление(вьюху если удобнее) заменить данные в базе данных на те которые ввел пользователь.

    Данные мне необходимо редактировать только в таблице schedule, остальные таблицы использую для логической связи между данными.
    • Изменено akavoid 4 октября 2012 г. 17:54
    4 октября 2012 г. 17:52
  • Да, в действительности в большинстве случаев без  DTO не обойтись, что Вы и делаете. "Все отлично с помощью моей модели я могу вывести данные, но я не могу сделать так, что бы с этой же моделью я работал для того что бы изменить таблицы в базе данных, т.е. я не могу понять, как заставить мое представление типа Edit представление(вьюху если удобнее) заменить данные в базе данных на те которые ввел пользователь." - вам нужны сервисные классы (обычно они помещаются в репозиторий) методы которых и будут разбирать объекты DTO и выполнять логику связанную с объявлением. В общем схема такая: контроллер получает данные в виде DTO объекта (Ваш ScheduleViewModel) вызывает метод репозитория (слоя доступа к данным) передав ему данный объект, то разбирает его и делает своё дело, обновляет данные.
    • Предложено в качестве ответа YatajgaEditor 10 октября 2012 г. 5:44
    • Помечено в качестве ответа Abolmasov Dmitry 12 октября 2012 г. 12:49
    • Снята пометка об ответе akavoid 15 октября 2012 г. 13:44
    • Помечено в качестве ответа akavoid 16 октября 2012 г. 18:42
    6 октября 2012 г. 19:20
    Модератор
  • Я попытался сделать так как вы посоветовали но не получилось, вот текст ошибки:

    Инструкции по обновлению, вставке или удалению из хранилища затронули непредвиденное число строк (0). Сущности могли быть изменены или удалены с момента их загрузки. Обновите записи диспетчера ObjectStateManager.

    Все так же как и в прошлый раз.

    Вот код:

    public List<Schedules> ConvertToScheduleList(ScheduleViewModel schedule)
            {
                List<Schedules> SchedulList = new List<Schedules>();
                for (int i = 0; i < 7; i++)
                {
                    Schedules SingleSchedule = new Schedules();
                    SingleSchedule.DayId = i;
                    SingleSchedule.GroupId = schedule.GroupId;
                    switch (i)
                    {
                        case 0:
                            SingleSchedule.Time = schedule.MondayTime;
                            break;
                        case 1:
                            SingleSchedule.Time = schedule.TuesdayTime;
                            break;
                        case 2:
                            SingleSchedule.Time = schedule.WednesdayTime;
                            break;
                        case 3:
                            SingleSchedule.Time = schedule.ThursdayTime;
                            break;
                        case 4:
                            SingleSchedule.Time = schedule.FridayTime;
                            break;
                        case 5:
                            SingleSchedule.Time = schedule.SaturdayTime;
                            break;
                        case 6:
                            SingleSchedule.Time = schedule.SundayTime;
                            break;
                    }
                    SchedulList.Add(SingleSchedule);
                }
                return SchedulList;
            }
    
            public void EditScheduleInDataBase(List<Schedules> SchedulList)
            {
                foreach (var schedule in SchedulList)
                {
                    EditSchedule(schedule);
                }
            }
            public void EditSchedule(Schedules schedule)
            {
                db.Entry(schedule).State = EntityState.Modified;
                db.SaveChanges();
            }

    14 октября 2012 г. 8:49
  • Не вызывайте метод db.Save для каждого объекта, это ресурсоёмкая операция, а сохраняйте их порциями, одновременно весь лист. И ещё добавляйте записи так:

    public void EditSchedule(Schedules schedule)
            {
                db.Shcedules.Add(schedule);
                db.Entry(schedule).State = EntityState.Modified;
                db.SaveChanges();
            }

    16 октября 2012 г. 5:46
    Модератор
  • я не добавляю записи я их изменяю.
    16 октября 2012 г. 17:10
  • Тогда так:

    public void EditSchedule(Schedules schedule)
            {
                db.Shcedules.Attach(schedule);
                db.Entry(schedule).State = EntityState.Modified;
                db.SaveChanges();
            }

    16 октября 2012 г. 17:22
    Модератор
  • Основная проблема в том, что когда я работаю с кастомной моделью я теряю id записи из бд... и потому путаюсь.
    16 октября 2012 г. 17:41
  • Нужен список idшников, а как его возвращать из вьюхи? Вот в чем моя сложность.

    Это кастомная модель, она создана из списка моделей, путаюсь, помогите пожалуйста.

    16 октября 2012 г. 17:57
  • А разве у Вас Id не идут в представлении, при отображении?
    16 октября 2012 г. 18:03
    Модератор
  • спасибо вам я сам додумался.

    В общем надо было сделать так:

    хранить idшники во вьюхе с помощью вот таких записей

    @Html.HiddenFor(model => model.MondayTimeID);
            @Html.HiddenFor(model => model.TuesdayTimeID);
            @Html.HiddenFor(model => model.WednesdayTimeID);
            @Html.HiddenFor(model => model.ThursdayTimeID);
            @Html.HiddenFor(model => model.FridayTimeID);
            @Html.HiddenFor(model => model.SaturdayTimeID);
            @Html.HiddenFor(model => model.SundayTimeID);

    и собственно добавить эти поля в модель

    public class ScheduleViewModel
        {
                public int GroupId { get; set; }
                public string GroupName { get; set; }
                public string MondayTime { get; set; }
                public string TuesdayTime { get; set; }
                public string WednesdayTime { get; set; }
                public string ThursdayTime { get; set; }
                public string FridayTime { get; set; }
                public string SaturdayTime { get; set; }
                public string SundayTime { get; set; }

                public int MondayTimeID { get; set; }
                public int TuesdayTimeID { get; set; }
                public int WednesdayTimeID { get; set; }
                public int ThursdayTimeID { get; set; }
                public int FridayTimeID { get; set; }
                public int SaturdayTimeID { get; set; }
                public int SundayTimeID { get; set; }
        }

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

    • Помечено в качестве ответа akavoid 16 октября 2012 г. 18:42
    16 октября 2012 г. 18:42
  • Вообщем Id именно так и хранятся в скрытых полях, если не используются явно. Я думал у Вас это реализовано, и поэтому спросил в предыдущем посте. Нужно было с самого начала подойти с этой стороны, чтобы решение не затянулось. В следующий раз попытайтесь именно так и сделать. Насчёт модели нет, а рефакторить сохранение данных нужно, как именно я подсказал высше.

    16 октября 2012 г. 18:52
    Модератор