asp.net 实体框架异常处理

tcbh2hod  于 2022-12-15  发布在  .NET
关注(0)|答案(3)|浏览(171)

我有一个表单,它有一些字段,并与数据库的关系。我正在使用实体框架,我想在SQL服务器发送错误消息之前处理异常。例如,当用户在数字字段中输入字符串值赢或Web应用程序在SQL服务器处理之前处理异常。我写了这段代码,但它不适用于所有的异常。例如,如果字段为空或具有无效类型,则表示输入字符串格式不正确。

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);
                }
             }
        }
jgovgodb

jgovgodb1#

您应该首先在UI上进行验证,然后处理与实体框架相关的特定错误。
创建模型并使用数据注解:

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 )

现在,当有人试图输入非数字或超出范围的数字时,在错误数据被发送回控制器之前,将向用户显示错误。
要处理实体框架异常,请使用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

在将命令发送到数据库之前或之后,尝试处理上下文中的实体时出错。

tzdcorbm

tzdcorbm2#

您应该捕获SqlException,而不是捕获Exception。
SqlException有一个可以使用的数字属性:

catch (SqlException e)
{
   MessageBox.Show("Error number: "+e.Number + " - " + e.Message);
}
t0ybt7op

t0ybt7op3#

你应该做的是找到一个适合你的解决方案模型的架构。一般来说,我会在创建上下文之前进行验证。如果你的应用程序需要更多的验证,你可能需要为此创建一个验证层。

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;
            }
        }
    }
}

希望通过这个例子可以使验证逻辑的体系结构更加清晰。

相关问题