2013-04-14 2 views
1

Я создаю свой первый проект MVC и столкнулся с проблемой параллелизма обработки. Веб-приложение работало нормально (добавление, редактирование и удаление), прежде чем я решил добавить обработку параллелизма.ASP.Net MVC 3 timestamp is null

//Entity class Line 
public class Line 
{ 
    [Key] 
    [Required(ErrorMessage = "Please enter a line name")] 
    public string Name { get; set; } 

    [Required(ErrorMessage = "Please enter a Business Unit name")] 
    public string BU { get; set; } 

    [Required(ErrorMessage = "Please enter a Department name")] 
    public string Department { get; set; } 

    [Required(ErrorMessage = "Please enter a location of the line")] 
    public string Location { get; set; } 

    [Required(ErrorMessage = "Please enter a target output")] 
    [Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive target output")] 
    public int TargetOutput { get; set; } 

    [Required(ErrorMessage = "Please enter a target yiel")] 
    [Range(0.01, 1.00, ErrorMessage = "Please enter a positive number in range of 0.01 to 1.00")] 
    public Double TargetYield { get; set; } 

    [Timestamp] 
    public Byte[] Timestamp { get; set; } 
} 

код из контроллера:

// Saves changes to the Line 
    [HttpPost] 
    public ActionResult Edit(Line line) 
    { 
     if (ModelState.IsValid) 
     { 
      repository.SaveLine(line); 
      TempData["message"] = string.Format("{0} has been saved", line.Name); 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      // return to lines list if there is something wrong with the data 
      return View(line); 
     } 
    } 

код из Entity Framework класса хранилища (эта часть кода еще не конкурировали, в тот момент, когда параллелизм произошло это должно просто заменить метку времени с одним из БД и сохранить его еще раз):

// Save changes to the line or create new one if not exists 
    public void SaveLine(Line line) 
    { 
     // Checking if line with the same name already exists 

     //Line found = Lines.FirstOrDefault(l => l.Name == line.Name); 
     string found = Lines 
      .Select(l => l.Name) 
      .Where(n => n == line.Name) 
      .SingleOrDefault(); 

     if (found == null) 
     { 
      context.Lines.Add(line); 
     } 
     else 
     { 
      context.Entry(line).State = System.Data.EntityState.Modified; 
     } 

     //context.SaveChanges(); 

     try 
     { 
      context.SaveChanges(); 
     } 
     catch (DbUpdateConcurrencyException ex) 
     { 
      var entry = ex.Entries.Single(); 
      var dbvalues = (Line)entry.GetDatabaseValues().ToObject(); 
      line.Timestamp = dbvalues.Timestamp; 
      context.SaveChanges(); 
     } 

    } 

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

Операция обновления, вставки или удаления магазина влияет на неожиданное количество строк (0). Объекты могут быть изменены или удалены, поскольку объекты загружены. Обновить записи ObjectStateManager.

У меня есть отладка и проверка значения метки времени, она равна нулю. Но в базе данных 0x0000000000000814. Когда в следующем шаге временная метка заменяется на одну из базы данных и пытается сохранить ее снова, она вызывает одно и то же исключение.

Я не знаю, где я сделал ошибку, любая помощь очень ценится

Простите за мой английский. Спасибо

ответ

0

Решено: похоже, когда я пытаюсь снова сохранить код, он на самом деле все еще держит старый объект со старой меткой времени. Я переместил инструкцию try catch к контроллеру и изменил его, чтобы заменить timestamp и вернуть Edit View, когда произошел параллелизм. Теперь, когда пользователь нажимает кнопку «Сохранить», исключение не выбрасывается и данные сохраняются.

+0

У меня есть гораздо лучший подход для вас. Посмотрите мой код здесь, его фильтр действий, и вы получите уведомление на своем экране, какие поля старые. http://stackoverflow.com/questions/9731425/how-can-i-force-the-dbupdateconcurrencyexception-to-be-raised-even-if-i-am-passi/9742622#9742622 –

1

Вам нужно написать свою метку времени, чтобы она вернулась в вашу сущность.

Html.HiddenFor (о => o.Timestamp)

+0

Я забыл вставить мой взгляд, и я добавил @ Html.HiddenFor (model => model.Timestamp) к моему представлению. Он все еще делает такую ​​же проблему. – Whistler

+0

Я разместил @ Html.HiddenFor (model => model.Timestamp) в неправильном месте в представлении, вне формы начала. Теперь исправлено и работает с одним приложением, как должно, но все еще не работает, когда два. – Whistler

0

Он работает при запуске одного экземпляра приложения, но когда я запускаю два из них для тестирования параллелизма. Я получаю исключение, которое я обработал и заменить метку время с одной из БДА, но это же исключение воскрешено, даже если оба временных меток одинаково: От немедленного окна:

?line.Timestamp 
{byte[8]} 
[0]: 0 
[1]: 0 
[2]: 0 
[3]: 0 
[4]: 0 
[5]: 0 
[6]: 70 
[7]: 81 
?dbValues.Timestamp 
{byte[8]} 
[0]: 0 
[1]: 0 
[2]: 0 
[3]: 0 
[4]: 0 
[5]: 0 
[6]: 70 
[7]: 81 

Почему? Должен ли он не только создавать исключения, когда временные метки различны?