2015-03-12 4 views
0

На моем View У меня есть кнопка, которую я использую для отправки значения [description] на мой Controller через JSON, который затем используется для создания новой записи Table. Например:Контроллер MVC5: проверьте наличие дубликатов в БД перед сохранением?

[HttpPost] 
    public JsonResult createNewStatus(string description) 
    { 
     INV_Statuses status = new INV_Statuses() 
     { 
      // ID auto-set during save 
      status_description = description, 
      created_date = DateTime.Now, 
      created_by = System.Environment.UserName 
     }; 

     //var allErrors = ModelState.Values.SelectMany(x => x.Errors); 

     try 
     { 
      if (ModelState.IsValid) 
      { 
       db.INV_Statuses.Add(status); 
       db.SaveChanges(); 
      } 

     } 
     catch (Exception ex) 
     { 
      Elmah.ErrorSignal.FromCurrentContext().Raise(ex); 
     } 

     return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet); 
    } 

То, что я хотел бы сделать сейчас (перед сохранением состояния в БД) выполняется проверка, чтобы увидеть, если какие-либо другие записи в таблице INV_Statuses имеют значение, соответствующее одно представленное [description] функция нового творения. Если есть совпадение, я хочу вернуть сообщение error/validation? и предупредить пользователя, что представленное значение уже существует, и выбрать его из DropDownList в представлении.

Может ли кто-нибудь представить пример того, как это сделать с LINQ в моем MVC-контроллере?


EDIT: Добавлен мой View JS код для представления нового статуса:

 $('#createNewStatus').click(function() { 
      $('#createStatusFormContainer').show(); 
     }) 

     $('#cancelNewStatus').click(function() { 
      $('#createStatusFormContainer').hide(); 
     }) 

     $('#submitNewStatus').click(function() { 
      var form = $(this).closest('form'); 
      var data = { description: document.getElementById('textNewStatus').value }; 

      $.ajax({ 
       type: "POST", 
       dataType: "JSON", 
       url: '@Url.Action("createNewStatus", "INV_Assets")', 
       data: data, 
       success: function (resp) { 
        $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text)); 
        form[0].reset(); 
        $('#createStatusFormContainer').hide(); 
        var count = $('#selectStatus option').size(); 
        $("#selectStatus").prop('selectedIndex', count - 1); 
       }, 
       error: function() { 
        alert("ERROR!"); 
       } 
      }); 
     }); 

EDIT2:

предложение Adricadar в:

 INV_Statuses status = new INV_Statuses() 
     { 
      // ID auto-set during save 
      status_description = description, 
      created_date = DateTime.Now, 
      created_by = System.Environment.UserName 
     }; 

     try 
     { 
      var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper()); 
      var isDuplicateDescription = existingStatus != null; 

      if (isDuplicateDescription) 
      { 
       ModelState.AddModelError("Error", "[" + status.status_description + "] already exists in the database. Please select from the DropDownList."); 
      } 
      else if (ModelState.IsValid) 
      { 
       db.INV_Statuses.Add(status); 
       db.SaveChanges(); 
      } 
     } 
     catch (Exception ex) 
     { 
      Elmah.ErrorSignal.FromCurrentContext().Raise(ex); 
     } 

     return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet); 

Я добавил .ToUpper() в сравнении с контроллером, но даже если найдена совпадение с .ToUpper(), код ModelState.AddModelError() запускается, тогда код возвращается и не выдается сообщение об ошибке?

значение (хотя дубликат) все еще будет добавлен в DropDownList (визуально, а не в БД) через мой текущий код JS:

 $('#createNewStatus').click(function() { 
      $('#createStatusFormContainer').show(); 
     }) 

     $('#cancelNewStatus').click(function() { 
      $('#createStatusFormContainer').hide(); 
     }) 

     $('#submitNewStatus').click(function() { 
      var form = $(this).closest('form'); 
      var data = { description: document.getElementById('textNewStatus').value }; 

      $.ajax({ 
       type: "POST", 
       dataType: "JSON", 
       url: '@Url.Action("createNewStatus", "INV_Assets")', 
       data: data, 
       success: function (resp) { 
        $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text)); 
        form[0].reset(); 
        $('#createStatusFormContainer').hide(); 
        var count = $('#selectStatus option').size(); 
        $("#selectStatus").prop('selectedIndex', count - 1); 
       }, 
       error: function() { 
        alert("ERROR!"); 
       } 
      }); 
     }); 
+1

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

+0

@RobertMcKee, Это хорошая идея. Любые мысли о том, как реализовать ограничение Unique в моем поле таблицы (пример) '[status_description]'? В настоящее время я использую локальную конструкцию DbMigrationsConfiguration через Code-First, но в PROD будут ссылаться на таблицы в ORACLE. –

+0

Извините, вам нужно спросить кого-нибудь другого, я всегда делаю Database First. –

ответ

1

Проверка для существующего статуса и установить статус обратно следующим образом:

var existingStatus = db.INV_Statuses.FirstOrDefault(s => s.status_description == description); 

if (existingStatus ==null) 
{ 
    db.INV_Statuses.Add(status); 
    db.SaveChanges(); 
} 
else 
{ 
    // set the status back to existing 
    status = existingStatus; 
} 

Установите существующий флаг в ответе:

return Json(new { ID = status.Id, Text = status.status_description, AlreadyExists = (existingStatus != null) }, JsonRequestBehavior.AllowGet); 

Затем в ответ JavaSc НИИИТ, просто разобрать возвращаемый данные:

success: function (resp) { 

if (resp.AlreadyExists != true) 
{ 
    $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text)); 
    form[0].reset(); 
    $('#createStatusFormContainer').hide(); 
    var count = $('#selectStatus option').size(); 
    $("#selectStatus").prop('selectedIndex', count - 1); 
     } 
     else 
     { 
     alert(resp.status_description + " already exists"); 
     $("#selectStatus").val(resp.Id); 
     } 
} 
+0

Спасибо, я сделаю это. Я думаю, что на вашем сегменте 'return Json' есть опечатки/пропущенные закрывающие скобки, но я не совсем уверен, где. –

+0

@AnalyticLunatic Извините, теперь я вижу опечатку, может быть больше, поскольку в окне браузера нет компилятора. :) – hutchonoid

+0

Хм ... Я немного смущен тем, как лучше всего структурировать код в контроллере, который у меня есть в настоящее время, с дополнениями, которые вы предложили? В настоящее время я проверяю переменную 'existingStatus', и если' null'/'Model.IsValid', я сохраняю статус. 'Else' Я устанавливаю' status = existingStatus', а затем возвращаю. Как бы я обработал возврат, точно учитывая мой возврат JSON на моем представлении с 'resp' check для' success/error'? (Добавление в EDIT). Наверное, я просто смущен тем, как 'existingStatus' используется по отношению к« успеху/ошибке »при возврате к просмотру? –

1

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

Знайте, что сравнение строк с учетом регистра.

[HttpPost] 
public JsonResult createNewStatus(string description) 
{ 
    INV_Statuses status = new INV_Statuses() 
    { 
     // ID auto-set during save 
     status_description = description, 
     created_date = DateTime.Now, 
     created_by = System.Environment.UserName 
    }; 

    //var allErrors = ModelState.Values.SelectMany(x => x.Errors); 

    try 
    { 
     var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper()); 
     var isDuplicateDescription = existingStatus != null; 

     string error = String.Empty; 
     if (isDuplicateDescription) 
     { 
      error = "[" + status.status_description + "] already exists in the database. Please select from the DropDownList."; 
     } 
     else if (ModelState.IsValid) 
     { 
      db.INV_Statuses.Add(status); 
      db.SaveChanges(); 
     } 

    } 
    catch (Exception ex) 
    { 
     Elmah.ErrorSignal.FromCurrentContext().Raise(ex); 
    } 

    return Json(new { ID = status.Id, Text = status.status_description, Error = error , IsDuplicate = isDuplicateDescription }, JsonRequestBehavior.AllowGet); 
} 

В javascript проверить, если ответ есть IsDuplicate = true, если это правда, что вы пропустите ту часть, где вам нужно добавить элемент в раскрывающемся списке.

$('#createNewStatus').click(function() { 
     $('#createStatusFormContainer').show(); 
    }) 

    $('#cancelNewStatus').click(function() { 
     $('#createStatusFormContainer').hide(); 
    }) 

    $('#submitNewStatus').click(function() { 
     var form = $(this).closest('form'); 
     var data = { description: document.getElementById('textNewStatus').value }; 

     $.ajax({ 
      type: "POST", 
      dataType: "JSON", 
      url: '@Url.Action("createNewStatus", "INV_Assets")', 
      data: data, 
      success: function (resp) { 
       if(resp.IsDuplicate) 
       { 
        //display error from response 
        //display resp.Error 
       } else { 
        $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text)); 
        form[0].reset(); 
        $('#createStatusFormContainer').hide(); 
        var count = $('#selectStatus option').size(); 
        $("#selectStatus").prop('selectedIndex', count - 1); 
       } 
      }, 
      error: function() { 
       alert("ERROR!"); 
      } 
     }); 
    }); 
+0

Спасибо adricadar. Я попробовал ваше предложение, но столкнулся с каким-то странным поведением. См. Мой EDIT2. –

+0

@AnalyticLunatic я видел ваш edit2, вы получаете дубликат записи в выпадающем списке, потому что вы не проверяли 'javascript', чтобы узнать, является ли это дублирующее описание. Смотрите мой отредактированный код 'C#' и 'Javascript' – adricadar

Смежные вопросы