在使用实体框架保存对SQL Server数据库的更改时,一个或多个实体的验证失败

时间:2023-01-19 02:15:21

I want to save my Edit to Database and I am using Entity FrameWork Code-First in ASP.NET MVC 3 / C# but I am getting errors. In my Event class, I have DateTime and TimeSpan datatypes but in my database, I've got Date and time respectively. Could this be the reason? How can I cast to the appropriate datatype in the code before saving changes to database.

我想将我的编辑保存到数据库中,并且我正在使用ASP中的实体框架代码- first。但是我有错误。在事件类中,我有DateTime和TimeSpan数据类型,但是在数据库中,我分别有日期和时间。这可能是原因吗?在保存对数据库的更改之前,如何在代码中转换到适当的数据类型。

public class Event
{
    public int EventId { get; set; }
    public int CategoryId { get; set; }
    public int PlaceId { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
    public DateTime EventDate { get; set; }
    public TimeSpan StartTime { get; set; }
    public TimeSpan EndTime { get; set; }
    public string Description { get; set; }
    public string EventPlaceUrl { get; set; }
    public Category Category { get; set; }
    public Place Place { get; set; }
}

Method in the controller >>>> Problem at storeDB.SaveChanges();

方法在storeDB.SaveChanges()的控制器>>>>问题中;

// POST: /EventManager/Edit/386        
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
    var theEvent = storeDB.Events.Find(id);

    if (TryUpdateModel(theEvent))
    {
        storeDB.SaveChanges();
        return RedirectToAction("Index");
    }
    else
    {
        ViewBag.Categories = storeDB.Categories.OrderBy(g => g.Name).ToList();
        ViewBag.Places = storeDB.Places.OrderBy(a => a.Name).ToList();
        return View(theEvent);
    }
}

with

public class EventCalendarEntities : DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Place> Places { get; set; } 
}

SQL Server 2008 R2 Database / T-SQL

SQL Server 2008 R2数据库/ T-SQL

EventDate (Datatype = date)  
StartTime (Datatype = time)  
EndTime (Datatype = time)  

Http Form

Http表单

EventDate (Datatype = DateTime) e.g. 4/8/2011 12:00:00 AM  
StartTime (Datatype = Timespan/time not sure) e.g. 08:30:00  
EndTime (Datatype = Timespan/time not sure) e.g. 09:00:00  

Server Error in '/' Application.

“/”应用程序中的服务器错误。

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

一个或多个实体的验证失败。有关更多细节,请参见“EntityValidationErrors”属性。

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

描述:在当前web请求执行期间发生未处理的异常。请查看堆栈跟踪,以获得关于错误的更多信息,以及错误起源于代码的何处。

Exception Details: System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

异常详细信息:System.Data.Entity.Validation。DbEntityValidationException:一个或多个实体的验证失败。有关更多细节,请参见“EntityValidationErrors”属性。

Source Error:

源错误:

Line 75:             if (TryUpdateModel(theEvent))
Line 76:             {
Line 77:                 storeDB.SaveChanges();
Line 78:                 return RedirectToAction("Index");
Line 79:             }

Source File: C:\sep\MvcEventCalendar\MvcEventCalendar\Controllers\EventManagerController.cs Line: 77

源文件:C:\ 9月\ \ EventManagerController MvcEventCalendar \ MvcEventCalendar \控制器。cs线:77

Stack Trace:

堆栈跟踪:

[DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.]

[DbEntityValidationException:一个或多个实体的验证失败。有关更多细节,请参见“EntityValidationErrors”属性。

16 个解决方案

#1


828  

You can extract all the information from the DbEntityValidationException with the following code (you need to add the namespaces: System.Data.Entity.Validation and System.Diagnostics to your using list):

可以使用以下代码从DbEntityValidationException提取所有信息(需要添加名称空间:System.Data.Entity)。验证和系统。诊断到您的使用列表):

catch (DbEntityValidationException dbEx)
{
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            Trace.TraceInformation("Property: {0} Error: {1}", 
                                    validationError.PropertyName, 
                                    validationError.ErrorMessage);
        }
    }
}

#2


246  

No code change required:

不需要代码更改:

While you are in debug mode within the catch {...} block open up the "QuickWatch" window (Ctrl+Alt+Q) and paste in there:

当您在catch{…> > > > > > > > > > > > > > > > >打开“QuickWatch”窗口(Ctrl+Alt+Q),粘贴在那里:

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

or:

或者:

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

If you are not in a try/catch or don't have access to the exception object.

如果您没有尝试/捕获或没有访问异常对象。

This will allow you to drill down into the ValidationErrors tree. It's the easiest way I've found to get instant insight into these errors.

这将允许您深入到ValidationErrors树。这是我发现的最简单的方法,可以立即洞察这些错误。

#3


36  

In the case you have classes with same property names, here is a small extension to Praveen's answer:

在这种情况下,您有相同属性名称的类,下面是Praveen的回答的一个小扩展:

 catch (DbEntityValidationException dbEx)
 {
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
       foreach (var validationError in validationErrors.ValidationErrors)
       {
          Trace.TraceInformation(
                "Class: {0}, Property: {1}, Error: {2}",
                validationErrors.Entry.Entity.GetType().FullName,
                validationError.PropertyName,
                validationError.ErrorMessage);
       }
    }
 }

#4


22  

As an improvement to both Praveen and Tony, I use an override:

作为对Praveen和Tony的改进,我使用了一个重写:

public partial class MyDatabaseEntities : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                        validationErrors.Entry.Entity.GetType().FullName,
                        validationError.PropertyName,
                        validationError.ErrorMessage);
                }
            }

            throw;  // You can also choose to handle the exception here...
        }
    }
}

#5


5  

This code helped find my problem when I had issue with my Entity VAlidation Erros. It told me the exact problem with my Entity Definition. Try following code where you need to cover storeDB.SaveChanges(); in following try catch block.

当我遇到实体验证Erros时,这段代码帮助我找到了问题。它告诉我实体定义的确切问题。尝试使用需要覆盖storeDB.SaveChanges()的代码;在后面尝试捕捉块。

  try
{
         if (TryUpdateModel(theEvent))
         {
             storeDB.SaveChanges();
             return RedirectToAction("Index");
         }
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
    Exception raise = dbEx;
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            string message = string.Format("{0}:{1}", 
                validationErrors.Entry.Entity.ToString(),
                validationError.ErrorMessage);
            // raise a new exception nesting
            // the current instance as InnerException
            raise = new InvalidOperationException(message, raise);
        }
    }
    throw raise;
}

#6


5  

This implementation wrap entity exception to exception with detail text. It handles DbEntityValidationException, DbUpdateException, datetime2 range errors (MS SQL), and include key of invalid entity in message (useful when savind many entities at one SaveChanges call).

这个实现将实体异常与细节文本打包在一起。它处理DbEntityValidationException、DbUpdateException、datetime2范围错误(MS SQL),并在消息中包含无效实体的键(在一次SaveChanges调用中删除多个实体时很有用)。

First, override SaveChanges in DbContext class:

首先,重写DbContext类中的SaveChanges:

public class AppDbContext : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }   

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        try
        {
            return await base.SaveChangesAsync(cancellationToken);
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }

ExceptionHelper class:

ExceptionHelper类:

public class ExceptionHelper
{
    public static Exception CreateFromEntityValidation(DbEntityValidationException ex)
    {
        return new Exception(GetDbEntityValidationMessage(ex), ex);
    }

    public static string GetDbEntityValidationMessage(DbEntityValidationException ex)
    {
        // Retrieve the error messages as a list of strings.
        var errorMessages = ex.EntityValidationErrors
            .SelectMany(x => x.ValidationErrors)
            .Select(x => x.ErrorMessage);

        // Join the list to a single string.
        var fullErrorMessage = string.Join("; ", errorMessages);

        // Combine the original exception message with the new one.
        var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
        return exceptionMessage;
    }

    public static IEnumerable<Exception> GetInners(Exception ex)
    {
        for (Exception e = ex; e != null; e = e.InnerException)
            yield return e;
    }

    public static Exception CreateFromDbUpdateException(DbUpdateException dbUpdateException)
    {
        var inner = GetInners(dbUpdateException).Last();
        string message = "";
        int i = 1;
        foreach (var entry in dbUpdateException.Entries)
        {
            var entry1 = entry;
            var obj = entry1.CurrentValues.ToObject();
            var type = obj.GetType();
            var propertyNames = entry1.CurrentValues.PropertyNames.Where(x => inner.Message.Contains(x)).ToList();
            // check MS SQL datetime2 error
            if (inner.Message.Contains("datetime2"))
            {
                var propertyNames2 = from x in type.GetProperties()
                                        where x.PropertyType == typeof(DateTime) ||
                                            x.PropertyType == typeof(DateTime?)
                                        select x.Name;
                propertyNames.AddRange(propertyNames2);
            }

            message += "Entry " + i++ + " " + type.Name + ": " + string.Join("; ", propertyNames.Select(x =>
                string.Format("'{0}' = '{1}'", x, entry1.CurrentValues[x])));
        }
        return new Exception(message, dbUpdateException);
    }
}

#7


4  

I was getting this error today and couldn't work it out for a while, but I realised it was after adding some RequireAttributes to my models and that some development seed data was not populating all of the required fields.
So just a note that if you're getting this error whilst updating the database through some sort of init strategy like DropCreateDatabaseIfModelChanges then you have to make sure that your seed data fulfils and satisfies any model data validation attributes.

我今天犯了这个错误,暂时无法解决它,但我意识到它是在给我的模型添加一些RequireAttributes之后,一些开发种子数据并没有填充所有必需的字段。请注意,如果您在通过DropCreateDatabaseIfModelChanges之类的init策略更新数据库时遇到了这个错误,那么您必须确保您的种子数据符合并满足任何模型数据验证属性。

I know this is slightly different to the problem in the question, but it's a popular question so I thought I'd add a bit more to the answer for others having the same issue as myself.
Hope this helps others :)

我知道这与问题中的问题略有不同,但这是一个很受欢迎的问题,所以我想我应该给其他有同样问题的人增加一些答案。希望这对其他人有所帮助。

#8


4  

I think adding try/catch for every SaveChanges() operation is not a good practice, it's better to centralize this :

我认为为每一个SaveChanges()操作添加try/catch都不是一个好的实践,最好将它集中起来:

Add this class to the main DbContext class :

将这个类添加到主DbContext类:

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage));
        throw new DbEntityValidationException(errorMessages);
    }
}

This will overwrite your context's SaveChanges() method and you'll get a comma separated list containing all the entity validation errors.

这将覆盖上下文的SaveChanges()方法,您将得到一个逗号分隔的列表,其中包含所有实体验证错误。

this also can improved, to log errors in production env, instead of just throwing an error.

这也可以改进,在生产环境v中记录错误,而不仅仅是抛出错误。

hope this is helpful.

希望这是有帮助的。

#9


3  

Here's an extension to Tony's extension... :-)

这是东尼的分机……:-)

For Entity Framework 4.x, if you want to get the name and value of the key field so that you know which entity instance (DB record) has the problem, you can add the following. This provides access to the more powerful ObjectContext class members from your DbContext object.

实体框架4。如果您想获取key字段的名称和值,以便知道哪个实体实例(DB记录)有问题,可以添加以下内容。这提供了对来自DbContext对象的更强大的ObjectContext类成员的访问。

// Get the key field name & value.
// This assumes your DbContext object is "_context", and that it is a single part key.
var e = ((IObjectContextAdapter)_context).ObjectContext.ObjectStateManager.GetObjectStateEntry(validationErrors.Entry.Entity);
string key = e.EntityKey.EntityKeyValues[0].Key;
string val = e.EntityKey.EntityKeyValues[0].Value;

#10


3  

I dont like exceptions I registered the OnSaveChanges and have this

我不喜欢例外,我注册了OnSaveChanges并拥有这个

var validationErrors = model.GetValidationErrors();

var h = validationErrors.SelectMany(x => x.ValidationErrors
                                          .Select(f => "Entity: " 
                                                      +(x.Entry.Entity) 
                                                      + " : " + f.PropertyName 
                                                      + "->" + f.ErrorMessage));

#11


2  

This error also happens when you try to save an entity that has validation errors. A good way to cause this is to forget to check ModelState.IsValid before saving to your DB.

当您试图保存具有验证错误的实体时,也会发生此错误。导致这种情况的一个好方法是忘记检查ModelState。在保存到您的数据库之前是有效的。

#12


2  

Make sure that if you have nvarchar(50)in DB row you don't trying to insert more than 50characters in it. Stupid mistake but took me 3 hours to figure it out.

确保如果在DB行中有nvarchar(50),那么就不要试图插入超过50个字符。愚蠢的错误,但我花了3个小时才弄明白。

#13


1  

This might be due to the maximum number of characters allowed for a specific column, like in sql one field might have following Data Type nvarchar(5) but the number of characters entered from the user is more than the specified, hence the error arises.

这可能是由于特定列允许的最大字符数,例如在sql one字段中,可能具有以下数据类型nvarchar(5),但是用户输入的字符数大于指定的字符数,因此会出现错误。

#14


1  

I have faced same issue a couple of days ago while updating the database. In my case, there was few new non nullable columns added for maintenance which was not supplied in the code which is causing the exception. I figure out those fields and supplied values for them and its resolved.

几天前我在更新数据库时遇到了同样的问题。在我的例子中,几乎没有添加用于维护的新的非空列,这在导致异常的代码中没有提供。我计算出这些字段,并为它们提供值,并解析它们。

#15


0  

Thnaks for your answers, it help me alot. as i code in Vb.Net, this Bolt code for Vb.Net

谢谢你的回答,它对我很有帮助。我用Vb编程。Net,这是Vb.Net的螺栓代码。

Try
   Return MyBase.SaveChanges()
Catch dbEx As Validation.DbEntityValidationException
   For Each [error] In From validationErrors In dbEx.EntityValidationErrors
                       From validationError In validationErrors.ValidationErrors
                       Select New With { .PropertyName = validationError.PropertyName,
                                         .ErrorMessage = validationError.ErrorMessage,
                                         .ClassFullName = validationErrors.Entry.Entity
                                                                    .GetType().FullName}

        Diagnostics.Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                                           [error].ClassFullName,
                                           [error].PropertyName,
                                           [error].ErrorMessage)
   Next
   Throw
End Try

#16


0  

it may caused by Property which is not populated by model.. instead it is populated by Controller.. which may cause this error.. solution to this is assign the property before applying ModelState validation. and this second Assumption is . you may have already have Data in your Database and trying to update it it but now fetching it.

它可能是由没有模型填充的属性引起的。而是由控制器填充。这可能会引起误差。解决方法是在应用ModelState验证之前分配属性。第二个假设是。您可能已经在数据库中拥有数据并试图更新它,但现在正在获取它。

#1


828  

You can extract all the information from the DbEntityValidationException with the following code (you need to add the namespaces: System.Data.Entity.Validation and System.Diagnostics to your using list):

可以使用以下代码从DbEntityValidationException提取所有信息(需要添加名称空间:System.Data.Entity)。验证和系统。诊断到您的使用列表):

catch (DbEntityValidationException dbEx)
{
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            Trace.TraceInformation("Property: {0} Error: {1}", 
                                    validationError.PropertyName, 
                                    validationError.ErrorMessage);
        }
    }
}

#2


246  

No code change required:

不需要代码更改:

While you are in debug mode within the catch {...} block open up the "QuickWatch" window (Ctrl+Alt+Q) and paste in there:

当您在catch{…> > > > > > > > > > > > > > > > >打开“QuickWatch”窗口(Ctrl+Alt+Q),粘贴在那里:

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

or:

或者:

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

If you are not in a try/catch or don't have access to the exception object.

如果您没有尝试/捕获或没有访问异常对象。

This will allow you to drill down into the ValidationErrors tree. It's the easiest way I've found to get instant insight into these errors.

这将允许您深入到ValidationErrors树。这是我发现的最简单的方法,可以立即洞察这些错误。

#3


36  

In the case you have classes with same property names, here is a small extension to Praveen's answer:

在这种情况下,您有相同属性名称的类,下面是Praveen的回答的一个小扩展:

 catch (DbEntityValidationException dbEx)
 {
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
       foreach (var validationError in validationErrors.ValidationErrors)
       {
          Trace.TraceInformation(
                "Class: {0}, Property: {1}, Error: {2}",
                validationErrors.Entry.Entity.GetType().FullName,
                validationError.PropertyName,
                validationError.ErrorMessage);
       }
    }
 }

#4


22  

As an improvement to both Praveen and Tony, I use an override:

作为对Praveen和Tony的改进,我使用了一个重写:

public partial class MyDatabaseEntities : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                        validationErrors.Entry.Entity.GetType().FullName,
                        validationError.PropertyName,
                        validationError.ErrorMessage);
                }
            }

            throw;  // You can also choose to handle the exception here...
        }
    }
}

#5


5  

This code helped find my problem when I had issue with my Entity VAlidation Erros. It told me the exact problem with my Entity Definition. Try following code where you need to cover storeDB.SaveChanges(); in following try catch block.

当我遇到实体验证Erros时,这段代码帮助我找到了问题。它告诉我实体定义的确切问题。尝试使用需要覆盖storeDB.SaveChanges()的代码;在后面尝试捕捉块。

  try
{
         if (TryUpdateModel(theEvent))
         {
             storeDB.SaveChanges();
             return RedirectToAction("Index");
         }
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
    Exception raise = dbEx;
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            string message = string.Format("{0}:{1}", 
                validationErrors.Entry.Entity.ToString(),
                validationError.ErrorMessage);
            // raise a new exception nesting
            // the current instance as InnerException
            raise = new InvalidOperationException(message, raise);
        }
    }
    throw raise;
}

#6


5  

This implementation wrap entity exception to exception with detail text. It handles DbEntityValidationException, DbUpdateException, datetime2 range errors (MS SQL), and include key of invalid entity in message (useful when savind many entities at one SaveChanges call).

这个实现将实体异常与细节文本打包在一起。它处理DbEntityValidationException、DbUpdateException、datetime2范围错误(MS SQL),并在消息中包含无效实体的键(在一次SaveChanges调用中删除多个实体时很有用)。

First, override SaveChanges in DbContext class:

首先,重写DbContext类中的SaveChanges:

public class AppDbContext : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }   

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        try
        {
            return await base.SaveChangesAsync(cancellationToken);
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }

ExceptionHelper class:

ExceptionHelper类:

public class ExceptionHelper
{
    public static Exception CreateFromEntityValidation(DbEntityValidationException ex)
    {
        return new Exception(GetDbEntityValidationMessage(ex), ex);
    }

    public static string GetDbEntityValidationMessage(DbEntityValidationException ex)
    {
        // Retrieve the error messages as a list of strings.
        var errorMessages = ex.EntityValidationErrors
            .SelectMany(x => x.ValidationErrors)
            .Select(x => x.ErrorMessage);

        // Join the list to a single string.
        var fullErrorMessage = string.Join("; ", errorMessages);

        // Combine the original exception message with the new one.
        var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
        return exceptionMessage;
    }

    public static IEnumerable<Exception> GetInners(Exception ex)
    {
        for (Exception e = ex; e != null; e = e.InnerException)
            yield return e;
    }

    public static Exception CreateFromDbUpdateException(DbUpdateException dbUpdateException)
    {
        var inner = GetInners(dbUpdateException).Last();
        string message = "";
        int i = 1;
        foreach (var entry in dbUpdateException.Entries)
        {
            var entry1 = entry;
            var obj = entry1.CurrentValues.ToObject();
            var type = obj.GetType();
            var propertyNames = entry1.CurrentValues.PropertyNames.Where(x => inner.Message.Contains(x)).ToList();
            // check MS SQL datetime2 error
            if (inner.Message.Contains("datetime2"))
            {
                var propertyNames2 = from x in type.GetProperties()
                                        where x.PropertyType == typeof(DateTime) ||
                                            x.PropertyType == typeof(DateTime?)
                                        select x.Name;
                propertyNames.AddRange(propertyNames2);
            }

            message += "Entry " + i++ + " " + type.Name + ": " + string.Join("; ", propertyNames.Select(x =>
                string.Format("'{0}' = '{1}'", x, entry1.CurrentValues[x])));
        }
        return new Exception(message, dbUpdateException);
    }
}

#7


4  

I was getting this error today and couldn't work it out for a while, but I realised it was after adding some RequireAttributes to my models and that some development seed data was not populating all of the required fields.
So just a note that if you're getting this error whilst updating the database through some sort of init strategy like DropCreateDatabaseIfModelChanges then you have to make sure that your seed data fulfils and satisfies any model data validation attributes.

我今天犯了这个错误,暂时无法解决它,但我意识到它是在给我的模型添加一些RequireAttributes之后,一些开发种子数据并没有填充所有必需的字段。请注意,如果您在通过DropCreateDatabaseIfModelChanges之类的init策略更新数据库时遇到了这个错误,那么您必须确保您的种子数据符合并满足任何模型数据验证属性。

I know this is slightly different to the problem in the question, but it's a popular question so I thought I'd add a bit more to the answer for others having the same issue as myself.
Hope this helps others :)

我知道这与问题中的问题略有不同,但这是一个很受欢迎的问题,所以我想我应该给其他有同样问题的人增加一些答案。希望这对其他人有所帮助。

#8


4  

I think adding try/catch for every SaveChanges() operation is not a good practice, it's better to centralize this :

我认为为每一个SaveChanges()操作添加try/catch都不是一个好的实践,最好将它集中起来:

Add this class to the main DbContext class :

将这个类添加到主DbContext类:

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage));
        throw new DbEntityValidationException(errorMessages);
    }
}

This will overwrite your context's SaveChanges() method and you'll get a comma separated list containing all the entity validation errors.

这将覆盖上下文的SaveChanges()方法,您将得到一个逗号分隔的列表,其中包含所有实体验证错误。

this also can improved, to log errors in production env, instead of just throwing an error.

这也可以改进,在生产环境v中记录错误,而不仅仅是抛出错误。

hope this is helpful.

希望这是有帮助的。

#9


3  

Here's an extension to Tony's extension... :-)

这是东尼的分机……:-)

For Entity Framework 4.x, if you want to get the name and value of the key field so that you know which entity instance (DB record) has the problem, you can add the following. This provides access to the more powerful ObjectContext class members from your DbContext object.

实体框架4。如果您想获取key字段的名称和值,以便知道哪个实体实例(DB记录)有问题,可以添加以下内容。这提供了对来自DbContext对象的更强大的ObjectContext类成员的访问。

// Get the key field name & value.
// This assumes your DbContext object is "_context", and that it is a single part key.
var e = ((IObjectContextAdapter)_context).ObjectContext.ObjectStateManager.GetObjectStateEntry(validationErrors.Entry.Entity);
string key = e.EntityKey.EntityKeyValues[0].Key;
string val = e.EntityKey.EntityKeyValues[0].Value;

#10


3  

I dont like exceptions I registered the OnSaveChanges and have this

我不喜欢例外,我注册了OnSaveChanges并拥有这个

var validationErrors = model.GetValidationErrors();

var h = validationErrors.SelectMany(x => x.ValidationErrors
                                          .Select(f => "Entity: " 
                                                      +(x.Entry.Entity) 
                                                      + " : " + f.PropertyName 
                                                      + "->" + f.ErrorMessage));

#11


2  

This error also happens when you try to save an entity that has validation errors. A good way to cause this is to forget to check ModelState.IsValid before saving to your DB.

当您试图保存具有验证错误的实体时,也会发生此错误。导致这种情况的一个好方法是忘记检查ModelState。在保存到您的数据库之前是有效的。

#12


2  

Make sure that if you have nvarchar(50)in DB row you don't trying to insert more than 50characters in it. Stupid mistake but took me 3 hours to figure it out.

确保如果在DB行中有nvarchar(50),那么就不要试图插入超过50个字符。愚蠢的错误,但我花了3个小时才弄明白。

#13


1  

This might be due to the maximum number of characters allowed for a specific column, like in sql one field might have following Data Type nvarchar(5) but the number of characters entered from the user is more than the specified, hence the error arises.

这可能是由于特定列允许的最大字符数,例如在sql one字段中,可能具有以下数据类型nvarchar(5),但是用户输入的字符数大于指定的字符数,因此会出现错误。

#14


1  

I have faced same issue a couple of days ago while updating the database. In my case, there was few new non nullable columns added for maintenance which was not supplied in the code which is causing the exception. I figure out those fields and supplied values for them and its resolved.

几天前我在更新数据库时遇到了同样的问题。在我的例子中,几乎没有添加用于维护的新的非空列,这在导致异常的代码中没有提供。我计算出这些字段,并为它们提供值,并解析它们。

#15


0  

Thnaks for your answers, it help me alot. as i code in Vb.Net, this Bolt code for Vb.Net

谢谢你的回答,它对我很有帮助。我用Vb编程。Net,这是Vb.Net的螺栓代码。

Try
   Return MyBase.SaveChanges()
Catch dbEx As Validation.DbEntityValidationException
   For Each [error] In From validationErrors In dbEx.EntityValidationErrors
                       From validationError In validationErrors.ValidationErrors
                       Select New With { .PropertyName = validationError.PropertyName,
                                         .ErrorMessage = validationError.ErrorMessage,
                                         .ClassFullName = validationErrors.Entry.Entity
                                                                    .GetType().FullName}

        Diagnostics.Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                                           [error].ClassFullName,
                                           [error].PropertyName,
                                           [error].ErrorMessage)
   Next
   Throw
End Try

#16


0  

it may caused by Property which is not populated by model.. instead it is populated by Controller.. which may cause this error.. solution to this is assign the property before applying ModelState validation. and this second Assumption is . you may have already have Data in your Database and trying to update it it but now fetching it.

它可能是由没有模型填充的属性引起的。而是由控制器填充。这可能会引起误差。解决方法是在应用ModelState验证之前分配属性。第二个假设是。您可能已经在数据库中拥有数据并试图更新它,但现在正在获取它。