我想保存我的编辑到数据库,我使用实体框架代码-在ASP。NET MVC 3 / c#,但我得到错误。在我的事件类中,我有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; }
}

方法>>>>在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);
    }
}

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数据库

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

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  

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

一个或多个实体验证失败。更多细节请参见'EntityValidationErrors'属性。

描述:在执行当前web请求期间发生了一个未处理的异常。请查看堆栈跟踪以获得有关错误及其在代码中的起源位置的更多信息。

System.Data.Entity.Validation.DbEntityValidationException:一个或多个实体验证失败。更多细节请参见'EntityValidationErrors'属性。

源错误:

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

源文件:C:\sep\MvcEventCalendar\MvcEventCalendar\Controllers\EventManagerController.cs

堆栈跟踪:

[DbEntityValidationException:一个或多个实体验证失败。]更多细节请参见'EntityValidationErrors'属性。]


当前回答

当我遇到实体验证错误时,这段代码帮助我找到了问题。它告诉我实体定义的确切问题。 尝试下面的代码,你需要覆盖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;
}

其他回答

当我遇到实体验证错误时,这段代码帮助我找到了问题。它告诉我实体定义的确切问题。 尝试下面的代码,你需要覆盖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;
}

您可以使用以下代码从DbEntityValidationException中提取所有信息(您需要添加名称空间:System. data . entity . validation和System. validationexception)。诊断到您的使用列表):

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

我认为为每个SaveChanges()操作添加try/catch并不是一个好的实践,最好集中这个:

将这个类添加到主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);
    }
}

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

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

希望这对你有帮助。

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

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

实体框架4。x,如果您想获得关键字段的名称和值,以便您知道哪个实体实例(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;