MVC вставка значений в ViewModel после отображения модели в ViewModel - PullRequest
0 голосов
/ 07 ноября 2018

Я работаю с двумя разными базами данных. Я передаю коллекцию Model (SQL Server) в коллекцию ViewModel. ViewModel имеет дополнительные свойства, к которым я обращаюсь из базы данных Visual Fox Pro. Я могу отобразить существующие свойства, но ViewModel не сохраняет данные после передачи значений.

Поля WoCust и Lname возвращают null, но остальные свойства, которые исходят из исходной модели, передаются свойствам в штрафе ViewModel.

Когда я отлаживаю в rdr для OleDbCommand, это показывает, что ViewModel получает значение для rdr[WoCust] и rdr[Lname].

Как мне сделать так, чтобы ViewModel сохранял новые значения?

WOSchedule.cs ...

public partial class WOSchedule
{
    public long Id { get; set; }
    public string WoNo { get; set; }
    public Nullable<long> QuoteTypeId { get; set; }
    public Nullable<int> PriorityNo { get; set; }
    public bool Active { get; set; }
    public Nullable<System.DateTime> WoDate { get; set; }
    public Nullable<long> QuoteID { get; set; }
    public Nullable<System.DateTime> WoDone { get; set; }
    public Nullable<long> WOScheduleListId { get; set; }
    public string StorageLocation { get; set; }

    public virtual QuoteType QuoteType { get; set; }
    public virtual Quote Quote { get; set; }
    public virtual WOScheduleList WOScheduleList { get; set; }
}

WoWcheduleVM.cs ...

public partial class WoScheduleVM
{
    public long Id { get; set; }
    public string WoNo { get; set; }
    public Nullable<long> QuoteTypeId { get; set; }
    public Nullable<int> PriorityNo { get; set; }
    public bool Active { get; set; }
    public DateTime? WoDate { get; set; }
    public Nullable<long> QuoteID { get; set; }
    public DateTime? WoDone { get; set; }
    public Nullable<long> WOScheduleListId { get; set; }
    public string StorageLocation { get; set; }

    public string WoCust { get; set; } // extra property
    public string Lname { get; set; } // extra property

    public virtual QuoteType QuoteType { get; set; }
    public virtual Quote Quote { get; set; }
    public virtual WOScheduleList WOScheduleList { get; set; }
}

WOSchedulesController.cs

string cs = ConfigurationManager.ConnectionStrings["foxproTables"].ConnectionString;
OleDbConnection cn = new OleDbConnection(cs);
var wOSchedules = db.WOSchedules.Where(w => w.WoDone == null).Include(w => w.QuoteType);

var wOSchedulesVM = wOSchedules.Select(s => new ViewModels.WoScheduleVM()
  {
     Id = s.Id,
     WoNo = s.WoNo,
     QuoteTypeId = s.QuoteTypeId,
     PriorityNo = s.PriorityNo,
     Active = s.Active,
     WoDate = s.WoDate,
     QuoteID = s.QuoteID,
     WoDone = s.WoDone,
     WOScheduleListId = s.WOScheduleListId,
     StorageLocation = s.StorageLocation
   });

cn.Open();
foreach (var sch in wOSchedulesVM)
  {
    string conn = @"SELECT wo_cust, lname FROM womast INNER JOIN custmast ON womast.wo_cust = custmast.cust_id WHERE wo_no = '" + sch.WoNo + "'";
    OleDbCommand cmdWO = new OleDbCommand(conn, cn);
    OleDbDataReader rdr = cmdWO.ExecuteReader();
    while (rdr.Read())
    {
      sch.WoCust = ((string)rdr["wo_cust"]).Trim();
      sch.Lname = ((string)rdr["lname"]).Trim();
    }
  }
cn.Close();

return View(wOSchedulesVM.OrderByDescending(d => d.WoDate).ToList());

1 Ответ

0 голосов
/ 08 ноября 2018

Проблема в том, что вы используете цикл foreach для итерации коллекции wOSchedulesVM, что делает исходную коллекцию неизменной во время итерации. более старая версия документации явно объясняет такое поведение:

Инструкция foreach используется для перебора коллекции, чтобы получить информация, которую вы хотите, но не может быть использована для добавления или удаления предметы из исходной коллекции , чтобы избежать непредсказуемых побочных эффектов. Если вам нужно добавить или удалить элементы из исходной коллекции, используйте цикл for.

Следовательно, вы должны использовать цикл for, чтобы иметь возможность изменять значения свойств внутри этой коллекции, как показано в примере ниже:

using (var OleDbConnection cn = new OleDbConnection(cs))
{
    cn.Open();
    string cmd = @"SELECT wo_cust, lname FROM womast INNER JOIN custmast ON womast.wo_cust = custmast.cust_id WHERE wo_no = @WoNo";

    // not sure if it's 'Count' property or 'Count()' method, depending on collection type
    for (int i = 0; i < wOSchedulesVM.Count; i++)
    {
        var sch = wOSchedulesVM[i];
        using (OleDbCommand cmdWO = new OleDbCommand(conn, cn))
        {
            cmd.Parameters.AddWithValue("@WoNo", sch.WoNo)
            OleDbDataReader rdr = cmdWO.ExecuteReader();
            if (rdr.HasRows)
            {
                while (rdr.Read())
                {
                    sch.WoCust = (!rdr.IsDbNull(0)) ? rdr.GetString(0).Trim() : string.Empty;
                    sch.Lname = (!rdr.IsDbNull(1)) ? rdr.GetString(1).Trim() : string.Empty;
                }
            }
        }
    }
}

Примечание: Этот пример включает в себя 3 дополнительных аспекта: параметризованный запрос, проверку существования строки с помощью свойства HasRows и проверку на DBNull.Value с помощью IsDbNull().

Связанная проблема: Каков наилучший способ изменить список в цикле 'foreach'?

...