Обработка исключений в Entity Framework
У меня есть форма, которая имеет некоторое поле и имеет отношение к базе данных. Я использую entity framework, я хочу обработать исключение перед отправкой сообщения об ошибке sql server. Например, когда пользователь вводит строковое значение в поле Номер win или исключение дескриптора веб-приложения перед обработкой sql server. Я написал этот код, но он не работает для всех исключений. Например, если поле было пустым или имеет недопустимый тип, указанная входная строка имеет неправильный формат.
using (var context = new entityTestEntities2())
{
try
{
int stNumber = Convert.ToInt32(textBox2.Text);
var allCustomers = context.setcust(null, stNumber);
}
catch(Exception ex)
{
if (ex.Message.Contains("correct format"))
{
int x= System.Runtime.InteropServices.Marshal.GetExceptionCode();
MessageBox.Show("error number"+x.ToString()+ex.Message);
}
}
}
3 ответов
что вы должны сделать, это найти архитектуру, которая соответствует модели вашего решения. В общем я бы сделал проверку перед созданием контекста. Если вам нужно больше проверки в приложении, вы можете создать слой проверки для этой цели.
public class RuleViolation
{
public string Property {get; set;}
public string Message {get; set;}
}
public class Program
{
public static List<RuleViolation> GetRuleViolations(string[] parameters)
{
List<RuleViolation> validations = new List<RuleViolation>();
if(!int.TryParse(parameters[0], out new Int32()))
{
validations.Add(new RuleViolation{Message ="Input1 must be integer.", Property = "input1"});
}
//more validation
return validations;
}
public static void Main(string[] parameters)
{
var validations = GetRuleViolations(parameters);
if(validations.Any())
{
validations.ForEach(x=> Console.WriteLine(x.Message));
return;
}
int input1 = int.Parse(parameters[0]);
//after all your business logic are ok, then you can go to persistence layer to hit the database.
using (var context = new entityTestEntities2())
{
try
{
var allCustomers = context.setcust(null, input1);
}
catch(SqlException exc)
{
//here you might still get some exceptions but not about validation.
ExceptionManager.Log(exc);
//sometimes you may want to throw the exception to upper layers for handle it better over there!
throw;
}
}
}
}
надеюсь, что пример сделает более ясной архитектуру о логике проверки.
вместо ловли исключения вы должны поймать SqlException.
SqlException имеет свойство number, которое можно использовать:
catch (SqlException e)
{
MessageBox.Show("Error number: "+e.Number + " - " + e.Message);
}
сначала вы должны выполнить проверку пользовательского интерфейса, а затем обработать определенные ошибки, связанные с Entity Framework.
создайте модель и используйте аннотации данных:
using System.ComponentModel.DataAnnotations;
public class YourViewModel
{
[Required]
[Range(0, 15, ErrorMessage = "Can only be between 0 .. 15")]
public int stNumber { get; set; }
}
в вашем контроллере верните модель в представление:
var model = new YourViewModel();
return View(model);
свяжите текстовое поле с моделью, добавив модель в представление и используя некоторые помощники тегов:
@using YourProject.WebUI.Models
@model YourViewModel
@Html.TextBoxFor(m => m.stNumber )
@Html.ValidationMessageFor(m => m.stNumber )
теперь, когда кто-то пытается ввести не числовое или число, которое находится вне диапазона, ошибка будет отображается пользователю перед отправкой плохих данных обратно на контроллер.
для обработки исключений Entity Framework используйте try catch:
try
{
var entity = context.yourEntity.FirstOrDefault(o => o.Id == custId);
if (entity == null) return false;
entity.value= stNumber;
entity.ModifiedBy = userId;
entity.ModifiedDate = DateTime.Now;
Db.SaveChanges();
return true;
}
catch (DbUpdateException Ex)
{
Console.WriteLine(ex.InnerException.Message);
return false;
}
другие типы исключений включает:
DbUpdateException
произошла ошибка при отправке обновлений в базу данных.
DbUpdateConcurrencyException
команда базы данных не повлияла на ожидаемое количество строк. Обычно это указывает на оптимистичное нарушение параллелизма; то есть строка была изменена в базе данных с тех пор, как она была опрошена.
DbEntityValidationException
сохранение было прервано из-за ошибки проверки значений свойств сущности.
NotSupportedException
была предпринята попытка использовать неподдерживаемое поведение, такое как одновременное выполнение нескольких асинхронных команд в одном экземпляре контекста.
ObjectDisposedException
контекст или соединение были удалены.
InvalidOperationException
произошла ошибка при попытке обработать объекты в контексте до или после отправки команд база данных.