首页 文章

一个或多个实体的验证失败 . 有关详细信息,请参阅'EntityValidationErrors'属性

提问于
浏览
698

我在使用代码优先方法播种数据库时遇到此错误 .

一个或多个实体的验证失败 . 有关详细信息,请参阅“EntityValidationErrors”属性 .

说实话,我不知道如何检查验证错误的内容 . Visual Studio向我显示它是一个包含8个对象的数组,因此有8个验证错误 .

这与我以前的模型有关,但我做了一些修改,我在下面解释:

  • 我有一个名为Status的枚举,我将其更改为名为Status的类

  • 我将类ApplicantsPositionHistory更改为在同一个表中有2个外键

请原谅我的长代码,但我必须将其全部粘贴 . 在以下代码的最后一行中抛出异常 .

namespace Data.Model
{  
    public class Position
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]   
        public int PositionID { get; set; }

        [Required(ErrorMessage = "Position name is required.")]
        [StringLength(20, MinimumLength = 3, ErrorMessage = "Name should not be longer than 20 characters.")]
        [Display(Name = "Position name")]              
        public string name { get; set; }

        [Required(ErrorMessage = "Number of years is required")] 
        [Display(Name = "Number of years")]        
        public int yearsExperienceRequired { get; set; }

        public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
    }

    public class Applicant
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]      
        public int ApplicantID { get; set; }

        [Required(ErrorMessage = "Name is required")] 
        [StringLength(20, MinimumLength = 3, ErrorMessage="Name should not be longer than 20 characters.")]
        [Display(Name = "First and LastName")]
        public string name { get; set; }

        [Required(ErrorMessage = "Telephone number is required")] 
        [StringLength(10, MinimumLength = 3, ErrorMessage = "Telephone should not be longer than 20 characters.")]
        [Display(Name = "Telephone Number")]
        public string telephone { get; set; }

        [Required(ErrorMessage = "Skype username is required")] 
        [StringLength(10, MinimumLength = 3, ErrorMessage = "Skype user should not be longer than 20 characters.")]
        [Display(Name = "Skype Username")]
        public string skypeuser { get; set; }

        public byte[] photo { get; set; }

        public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
    }

    public class ApplicantPosition
    {
        [Key]
        [Column("ApplicantID", Order = 0)]
        public int ApplicantID { get; set; }

        [Key]
        [Column("PositionID", Order = 1)]
        public int PositionID { get; set; }

        public virtual Position Position { get; set; }

        public virtual Applicant Applicant { get; set; }

        [Required(ErrorMessage = "Applied date is required")] 
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date applied")]     
        public DateTime appliedDate { get; set; }

        [Column("StatusID", Order = 0)]
        public int StatusID { get; set; }

        public Status CurrentStatus { get; set; }

        //[NotMapped]
        //public int numberOfApplicantsApplied
        //{
        //    get
        //    {
        //        int query =
        //             (from ap in Position
        //              where ap.Status == (int)Status.Applied
        //              select ap
        //                  ).Count();
        //        return query;
        //    }
        //}
    }

    public class Address
    {
        [StringLength(20, MinimumLength = 3, ErrorMessage = "Country should not be longer than 20 characters.")]
        public string Country { get; set; }

        [StringLength(20, MinimumLength = 3, ErrorMessage = "City  should not be longer than 20 characters.")]
        public string City { get; set; }

        [StringLength(50, MinimumLength = 3, ErrorMessage = "Address  should not be longer than 50 characters.")]
        [Display(Name = "Address Line 1")]     
        public string AddressLine1 { get; set; }

        [Display(Name = "Address Line 2")]
        public string AddressLine2 { get; set; }   
    }

    public class ApplicationPositionHistory
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public int ApplicationPositionHistoryID { get; set; }

        public ApplicantPosition applicantPosition { get; set; }

        [Column("oldStatusID")]
        public int oldStatusID { get; set; }

        [Column("newStatusID")]
        public int newStatusID { get; set; }

        public Status oldStatus { get; set; }

        public Status newStatus { get; set; }

        [StringLength(500, MinimumLength = 3, ErrorMessage = "Comments  should not be longer than 500 characters.")]
        [Display(Name = "Comments")]
        public string comments { get; set; }

        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date")]     
        public DateTime dateModified { get; set; }
    }

    public class Status
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public int StatusID { get; set; }

        [StringLength(20, MinimumLength = 3, ErrorMessage = "Status  should not be longer than 20 characters.")]
        [Display(Name = "Status")]
        public string status { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.IO;

namespace Data.Model
{
    public class HRContextInitializer : DropCreateDatabaseAlways<HRContext>
    {
        protected override void Seed(HRContext context)
        {
            #region Status
            Status applied = new Status() { status = "Applied" };
            Status reviewedByHR = new Status() { status = "Reviewed By HR" };
            Status approvedByHR = new Status() { status = "Approved by HR" };
            Status rejectedByHR = new Status() { status = "Rejected by HR" };
            Status assignedToTechnicalDepartment = new Status() { status = "Assigned to Technical Department" };
            Status approvedByTechnicalDepartment = new Status() { status = "Approved by Technical Department" };
            Status rejectedByTechnicalDepartment = new Status() { status = "Rejected by Technical Department" };

            Status assignedToGeneralManager = new Status() { status = "Assigned to General Manager" };
            Status approvedByGeneralManager = new Status() { status = "Approved by General Manager" };
            Status rejectedByGeneralManager = new Status() { status = "Rejected by General Manager" };

            context.Status.Add(applied);
            context.Status.Add(reviewedByHR);
            context.Status.Add(approvedByHR);
            context.Status.Add(rejectedByHR);
            context.Status.Add(assignedToTechnicalDepartment);
            context.Status.Add(approvedByTechnicalDepartment);
            context.Status.Add(rejectedByTechnicalDepartment);
            context.Status.Add(assignedToGeneralManager);
            context.Status.Add(approvedByGeneralManager);
            context.Status.Add(rejectedByGeneralManager); 
            #endregion    

            #region Position
            Position netdeveloper = new Position() { name = ".net developer", yearsExperienceRequired = 5 };
            Position javadeveloper = new Position() { name = "java developer", yearsExperienceRequired = 5 };
            context.Positions.Add(netdeveloper);
            context.Positions.Add(javadeveloper); 
            #endregion

            #region Applicants
            Applicant luis = new Applicant()
            {
                name = "Luis",
                skypeuser = "le.valencia",
                telephone = "0491732825",
                photo = File.ReadAllBytes(@"C:\Users\LUIS.SIMBIOS\Documents\Visual Studio 2010\Projects\SlnHR\HRRazorForms\Content\pictures\1.jpg")
            };

            Applicant john = new Applicant()
            {
                name = "John",
                skypeuser = "jo.valencia",
                telephone = "3435343543",
                photo = File.ReadAllBytes(@"C:\Users\LUIS.SIMBIOS\Documents\Visual Studio 2010\Projects\SlnHR\HRRazorForms\Content\pictures\2.jpg")
            };

            context.Applicants.Add(luis);
            context.Applicants.Add(john); 
            #endregion

            #region ApplicantsPositions
            ApplicantPosition appicantposition = new ApplicantPosition()
            {
                Applicant = luis,
                Position = netdeveloper,
                appliedDate = DateTime.Today,
                StatusID = 1
            };

            ApplicantPosition appicantposition2 = new ApplicantPosition()
            {
                Applicant = john,
                Position = javadeveloper,
                appliedDate = DateTime.Today,
                StatusID = 1
            };        

            context.ApplicantsPositions.Add(appicantposition);            
            context.ApplicantsPositions.Add(appicantposition2); 
            #endregion

            context.SaveChanges(); --->> Error here
        }
    }
}

25 回答

  • 4

    对于在 VB.NET 工作的任何人

    Try
    Catch ex As DbEntityValidationException
        For Each a In ex.EntityValidationErrors
            For Each b In a.ValidationErrors
                Dim st1 As String = b.PropertyName
                Dim st2 As String = b.ErrorMessage
            Next
        Next
    End Try
    
  • 42

    把我的两分钱扔进......

    在我的dbConfiguration.cs中,我喜欢将我的context.SaveChanges()方法包装到try / catch中并生成一个输出文本文件,允许我清楚地读取错误,这段代码也为它们加上时间戳 - 如果你方便的话在不同的时间遇到多个错误!

    try
            {
                context.SaveChanges();
            }
            catch (DbEntityValidationException e)
            {
                //Create empty list to capture Validation error(s)
                var outputLines = new List<string>();
    
                foreach (var eve in e.EntityValidationErrors)
                {
                    outputLines.Add(
                        $"{DateTime.Now}: Entity of type \"{eve.Entry.Entity.GetType().Name}\" in state \"{eve.Entry.State}\" has the following validation errors:");
                    outputLines.AddRange(eve.ValidationErrors.Select(ve =>
                        $"- Property: \"{ve.PropertyName}\", Error: \"{ve.ErrorMessage}\""));
                }
                //Write to external file
                File.AppendAllLines(@"c:\temp\dbErrors.txt", outputLines);
                throw;
            }
    
  • 2

    使用@Slauma的答案,我已经制作了一个代码片段(带有代码片段的环绕声),以便更好地使用 .

    <?xml version="1.0" encoding="utf-8"?>
    <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
      <CodeSnippet Format="1.0.0">
        <Header>
          <SnippetTypes>
            <SnippetType>SurroundsWith</SnippetType>
          </SnippetTypes>
          <Title>ValidationErrorsTryCatch</Title>
          <Author>Phoenix</Author>
          <Description>
          </Description>
          <HelpUrl>
          </HelpUrl>
          <Shortcut>
          </Shortcut>
        </Header>
        <Snippet>
          <Code Language="csharp"><![CDATA[try
    {
        $selected$ $end$
    }
    catch (System.Data.Entity.Validation.DbEntityValidationException e)
    {
        foreach (var eve in e.EntityValidationErrors)
        {
            Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                eve.Entry.Entity.GetType().Name, eve.Entry.State);
            foreach (var ve in eve.ValidationErrors)
            {
                Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                    ve.PropertyName, ve.ErrorMessage);
            }
        }
        throw;
    }]]></Code>
        </Snippet>
      </CodeSnippet>
    </CodeSnippets>
    
  • 14

    在调试中,您可以在QuickWatch表达式评估程序输入字段中输入:

    context.GetValidationErrors()
    
  • 5

    说实话我不知道如何检查验证错误的内容 . Visual Studio向我显示它是一个包含8个对象的数组,因此有8个验证错误 .

    实际上,如果在调试期间在Visual Studio中钻入该数组,则应该看到错误 . 但您也可以捕获异常,然后将错误写入某些日志存储或控制台:

    try
    {
        // Your code...
        // Could also be before try if you know the exception occurs in SaveChanges
    
        context.SaveChanges();
    }
    catch (DbEntityValidationException e)
    {
        foreach (var eve in e.EntityValidationErrors)
        {
            Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                eve.Entry.Entity.GetType().Name, eve.Entry.State);
            foreach (var ve in eve.ValidationErrors)
            {
                Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                    ve.PropertyName, ve.ErrorMessage);
            }
        }
        throw;
    }
    

    EntityValidationErrors 是一个集合,表示无法成功验证的实体,每个实体的内部集合 ValidationErrors 是属性级别的错误列表 .

    这些验证消息通常足以找到问题的根源 .

    Edit

    一些小改进:

    有问题的属性的值可以包含在内部循环中,如下所示:

    foreach (var ve in eve.ValidationErrors)
            {
                Console.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                    ve.PropertyName,
                    eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                    ve.ErrorMessage);
            }
    

    虽然调试 Debug.Write 可能优于 Console.WriteLine ,因为它适用于所有类型的应用程序,不仅适用于控制台应用程序(感谢@Bart在下面的评论中的注释) .

    对于正在 生产环境 中并使用 Elmah 进行异常日志记录的Web应用程序,对我来说,创建自定义异常并覆盖 SaveChanges 以便抛出此新异常非常有用 .

    自定义异常类型如下所示:

    public class FormattedDbEntityValidationException : Exception
    {
        public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
            base(null, innerException)
        {
        }
    
        public override string Message
        {
            get
            {
                var innerException = InnerException as DbEntityValidationException;
                if (innerException != null)
                {
                    StringBuilder sb = new StringBuilder();
    
                    sb.AppendLine();
                    sb.AppendLine();
                    foreach (var eve in innerException.EntityValidationErrors)
                    {
                        sb.AppendLine(string.Format("- Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().FullName, eve.Entry.State));
                        foreach (var ve in eve.ValidationErrors)
                        {
                            sb.AppendLine(string.Format("-- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                                ve.PropertyName,
                                eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                                ve.ErrorMessage));
                        }
                    }
                    sb.AppendLine();
    
                    return sb.ToString();
                }
    
                return base.Message;
            }
        }
    }
    

    并且 SaveChanges 可以通过以下方式覆盖:

    public class MyContext : DbContext
    {
        // ...
    
        public override int SaveChanges()
        {
            try
            {
                return base.SaveChanges();
            }
            catch (DbEntityValidationException e)
            {
                var newException = new FormattedDbEntityValidationException(e);
                throw newException;
            }
        }
    }
    

    几点评论:

    • Elmah在Web界面或已发送的电子邮件中显示的黄色错误屏幕(如果已配置)现在直接在邮件顶部显示验证详细信息 .

    • 覆盖自定义异常中的 Message 属性而不是覆盖 ToString() ,这样做的好处是标准ASP.NET "Yellow screen of death (YSOD)"也显示此消息 . 与Elmah相比,YSOD显然不使用 ToString() ,但两者都显示 Message 属性 .

    • 将原始 DbEntityValidationException 包装为内部异常可确保原始堆栈跟踪仍然可用并显示在Elmah和YSOD中 .

    • 通过在 throw newException; 行上设置断点,您只需将 newException.Message 属性视为文本,而不是深入到验证集合中,这有点尴尬,似乎并不适合所有人(请参阅下面的注释) .

  • 5

    请检查您传递的字段值是否有效以及根据数据库字段 . 例如,在特定字段中传递的字符数小于在数据库表字段中定义的字符数 .

  • 88

    如果您使用 IISWindows AuthentificationEntity Framework ,请小心使用 authorize .

    我试图 POST 没有授权,它没有工作,并在 db.SaveChangesAsync(); 上得到此错误,而所有其他动词 GETDELETE 正在工作 .

    但是当我添加AuthorizeAttribute作为注释时,它起作用了 .

    [Authorize]
    public async Task<IHttpActionResult> Post(...){
    ....
    }
    
  • 2

    这实际上可以在不必编写代码的情况下完成:

    在catch块中,在以下代码行中添加一个断点:

    catch (Exception exception)
    {
    
    }
    

    现在,如果您将鼠标悬停在 exception 上或将其添加到 Watch ,然后导航到异常详细信息,如下所示;您将看到哪个特定列导致问题,因为当违反表约束时通常会发生此错误 .

    enter image description here

    Large image

  • 7

    在try catch中捕获异常,然后快速监视或按住Ctrl键,您可以深入查看EntityValidationErrors .

  • 10

    只需检查数据库表字段长度 . 输入文本大于列字段数据类型长度

  • 11

    要快速查看第一个错误而不添加 Watch ,您可以将其粘贴到立即数中窗口:

    ((System.Data.Entity.Validation.DbEntityValidationException)$exception)
        .EntityValidationErrors.First()
        .ValidationErrors.First()
    
  • 8

    这对我有用 .

    var modelState = ModelState.Values;
    if (!ModelState.IsValid)
    {
        return RedirectToAction("Index", "Home", model);
    }
    

    在if语句上加上断点 . 然后,您可以在调试窗口中检查modelState . 如果出现错误甚至错误消息,您可以看到每个值 . 而已 . 如果您不再需要它,只需删除或注释该行 .

    我希望这将有所帮助 .

    如果被问到,我可以在调试窗口中提供详细的屏幕截图 .

  • 400

    您可以在调试期间从Visual Studio中执行此操作而无需编写任何代码,甚至不能使用catch块 .

    只需添加一个名称为的 Watch :

    ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors
    

    监视表达式 $exception 显示当前上下文中抛出的任何异常,即使它尚未被捕获并分配给变量 .

    基于http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/

  • 9

    我必须在立即窗口中写这个:3

    (((exception as System.Data.Entity.Validation.DbEntityValidationException).EntityValidationErrors as System.Collections.Generic.List<System.Data.Entity.Validation.DbEntityValidationResult>)[0].ValidationErrors as System.Collections.Generic.List<System.Data.Entity.Validation.DbValidationError>)[0]
    

    为了深入了解确切的错误!

  • 3

    @Slauma的答案真的很棒,但我发现当ComplexType属性无效时它不起作用 .

    例如,假设您拥有复杂类型 PhoneNumber 的属性 Phone . 如果 AreaCode 属性无效,则 ve.PropertyNames 中的属性名称为"Phone.AreaCode" . 这会导致对 eve.Entry.CurrentValues<object>(ve.PropertyName) 的调用失败 .

    要解决此问题,您可以在每个 . 拆分属性名称,然后通过生成的属性名称数组进行递归 . 最后,当您到达链的底部时,您只需返回属性的值即可 .

    下面是@ Slauma的 FormattedDbEntityValidationException 类,支持ComplexTypes .

    请享用!

    [Serializable]
    public class FormattedDbEntityValidationException : Exception
    {
        public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
            base(null, innerException)
        {
        }
    
        public override string Message
        {
            get
            {
                var innerException = InnerException as DbEntityValidationException;
                if (innerException == null) return base.Message;
    
                var sb = new StringBuilder();
    
                sb.AppendLine();
                sb.AppendLine();
                foreach (var eve in innerException.EntityValidationErrors)
                {
                    sb.AppendLine(string.Format("- Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().FullName, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        object value;
                        if (ve.PropertyName.Contains("."))
                        {
                            var propertyChain = ve.PropertyName.Split('.');
                            var complexProperty = eve.Entry.CurrentValues.GetValue<DbPropertyValues>(propertyChain.First());
                            value = GetComplexPropertyValue(complexProperty, propertyChain.Skip(1).ToArray());
                        }
                        else
                        {
                            value = eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName);
                        }
                        sb.AppendLine(string.Format("-- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                            ve.PropertyName,
                            value,
                            ve.ErrorMessage));
                    }
                }
                sb.AppendLine();
    
                return sb.ToString();
            }
        }
    
        private static object GetComplexPropertyValue(DbPropertyValues propertyValues, string[] propertyChain)
        {
            var propertyName = propertyChain.First();
            return propertyChain.Count() == 1 
                ? propertyValues[propertyName] 
                : GetComplexPropertyValue((DbPropertyValues)propertyValues[propertyName], propertyChain.Skip(1).ToArray());
        }
    }
    
  • 1106

    如果您只是捕获一个通用异常,那么将其转换为 DbEntityValidationException 可能会对您有所帮助 . 这种类型的异常具有Validation Errors属性,并继续扩展您的方式,您将找到所有问题 .

    例如,如果在catch中放置一个断点,则可以将以下内容放入监视中:

    ((System.Data.Entity.Validation.DbEntityValidationException ) ex)
    

    错误的一个例子是 if a field does not allow nulls, and you have a null string, you'll see it say that the field is required.

  • 3

    检查表列中是否有 Not Null 约束,并且在插入/更新操作时不传递该列的值 . 这导致实体框架中的此异常 .

  • 1

    当你处于 catch {...} 块内的调试模式时,打开"QuickWatch"窗口(ctrl alt q)并粘贴到那里:

    ((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

    要么:

    ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

    如果您不在try / catch中,或者无法访问异常对象 .

    这将允许您深入查看 ValidationErrors 树 . 它已被发现可以立即了解这些错误 .

  • 6

    我之前遇到过这个错误

    当我试着update specific field in my model in entity framwork

    Letter letter = new Letter {ID = letterId, ExportNumber = letterExportNumber,EntityState = EntityState.Modified};
    LetterService.ChangeExportNumberfor(letter);
    //----------
    
    
    public int ChangeExportNumber(Letter letter)
        {
            int result = 0;
            using (var db = ((LettersGeneratorEntities) GetContext()))
            {
                db.Letters.Attach(letter);
                db.Entry(letter).Property(x => x.ExportNumber).IsModified = true;
                result += db.SaveChanges();
            }
            return result;
        }
    

    并根据上述答案

    我找到了验证消息 The SignerName field is required.

    它指向我模型中的字段

    当我检查我的数据库架构时,我找到了

    所以关闭coure ValidationException 有权提出

    根据这个领域,我希望它可以为空,(我不知道我是怎么搞砸的)

    所以我改变了那个字段以允许Null,由此我的代码不再给我这个错误

    so如果您使数据库的数据完整性无效,则可能会发生此错误

  • 0

    这是另一种方法,而不是使用foreach循环来查看EntityValidationErrors . 当然,您可以根据自己的喜好格式化消息:

    try {
            // your code goes here...
        } 
    catch (DbEntityValidationException ex) 
        {
            Console.Write($"Validation errors: {string.Join(Environment.NewLine, ex.EntityValidationErrors.SelectMany(vr => vr.ValidationErrors.Select(err => $"{err.PropertyName} - {err.ErrorMessage}")))}", ex);
            throw;
        }
    
  • 6

    我发现的......当我得到'EntityValidationErrors'错误是....我在表'tbladdress'的数据库'db1'中有一个字段为'address1',其大小为100(即地址varchar(100) null),我传递的值超过100个字符..这导致错误,同时将数据保存到数据库....

    因此,您必须检查要传递到该字段的数据 .

  • 4

    以下是如何检查Visual Studio中 EntityValidationErrors 的内容(无需编写任何额外代码),即在 IDEDebugging 期间 .

    问题?

    你是对的,Visual Studio调试器的 View Details Popup没有显示 EntityValidationErrors 集合中的实际错误 .

    解决方案!

    只需在 Quick Watch 窗口中添加以下表达式,然后单击 Reevaluate .

    ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

    就我而言,看看我如何能够扩展到 EntityValidationErrors 集合中的 ValidationErrors List

    References: mattrandle.me blog post@yoel's answer

  • 35

    正如其他帖子中所提到的,只需在DbEntityValidationException类中捕获异常即可 . 这将为您提供错误案例中所需的watever .

    try
     {
      ....
     }
     catch(DbEntityValidationException ex)
     {
      ....
     }
    
  • 0

    Per @ Slauma的答案和@Milton的建议我用一个try / catch扩展了我们的基类的自定义保存方法,它将处理(并因此登录我们的错误记录!)这些异常 .

    // Where `BaseDB` is your Entities object... (it could be `this` in a different design)
    public void Save(bool? validateEntities = null)
    {
        try
        {
            //Capture and set the validation state if we decide to
            bool validateOnSaveEnabledStartState = BaseDB.Configuration.ValidateOnSaveEnabled;
            if (validateEntities.HasValue)
                BaseDB.Configuration.ValidateOnSaveEnabled = validateEntities.Value;
    
            BaseDB.SaveChanges();
    
            //Revert the validation state when done
            if (validateEntities.HasValue)
                BaseDB.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabledStartState;
        }
        catch (DbEntityValidationException e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var eve in e.EntityValidationErrors)
            {
                sb.AppendLine(string.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", 
                                                eve.Entry.Entity.GetType().Name,
                                                eve.Entry.State));
                foreach (var ve in eve.ValidationErrors)
                {
                    sb.AppendLine(string.Format("- Property: \"{0}\", Error: \"{1}\"",
                                                ve.PropertyName,
                                                ve.ErrorMessage));
                }
            }
            throw new DbEntityValidationException(sb.ToString(), e);
        }
    }
    
  • 5

    请注意, Entity.GetType().BaseType.Name 给出了您指定的类型名称,而不是名称中包含所有十六进制数字的名称 .

相关问题