[c#] Validation failed for one or more entities while saving changes to SQL Server Database using Entity Framework

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.

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();

// 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

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

Http Form

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.

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.

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

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

Stack Trace:

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

This question is related to c# sql asp.net-mvc entity-framework code-first

The answer is


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.

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

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

Add this class to the main DbContext class :

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.

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

hope this is helpful.


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.


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.


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).

First, override SaveChanges in DbContext class:

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:

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

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.

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

I dont like exceptions I registered the OnSaveChanges and have this

var validationErrors = model.GetValidationErrors();

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

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.


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

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

In my case I have a Table Column name Path which datatype i set was varchar(200).After updating it to nvarchar(max), I have deleted the table from edmx and then again added the table and it wokred properly for me.


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.

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 :)


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.


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):

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

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.


Thnaks for your answers, it help me alot. as i code in Vb.Net, this Bolt code for 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

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:

((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.


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

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

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to sql

Passing multiple values for same variable in stored procedure SQL permissions for roles Generic XSLT Search and Replace template Access And/Or exclusions Pyspark: Filter dataframe based on multiple conditions Subtracting 1 day from a timestamp date PYODBC--Data source name not found and no default driver specified select rows in sql with latest date for each ID repeated multiple times ALTER TABLE DROP COLUMN failed because one or more objects access this column Create Local SQL Server database

Examples related to asp.net-mvc

Using Lato fonts in my css (@font-face) Better solution without exluding fields from Binding Vue.js get selected option on @change You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to send json data in POST request using C# VS 2017 Metadata file '.dll could not be found The default XML namespace of the project must be the MSBuild XML namespace How to create roles in ASP.NET Core and assign them to users? The model item passed into the dictionary is of type .. but this dictionary requires a model item of type How to use npm with ASP.NET Core

Examples related to entity-framework

Entity Framework Core: A second operation started on this context before a previous operation completed EF Core add-migration Build Failed Entity Framework Core add unique constraint code-first 'No database provider has been configured for this DbContext' on SignInManager.PasswordSignInAsync The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked Auto-increment on partial primary key with Entity Framework Core Working with SQL views in Entity Framework Core How can I make my string property nullable? Lazy Loading vs Eager Loading How to add/update child entities when updating a parent entity in EF

Examples related to code-first

ALTER TABLE DROP COLUMN failed because one or more objects access this column CREATE DATABASE permission denied in database 'master' (EF code-first) Nullable property to entity field, Entity Framework through Code First Why use ICollection and not IEnumerable or List<T> on many-many/one-many relationships? Entity Framework Code First - two Foreign Keys from same table Validation failed for one or more entities while saving changes to SQL Server Database using Entity Framework The model backing the <Database> context has changed since the database was created