use*_*767 333 c# sql asp.net-mvc entity-framework code-first
我想保存我的编辑到数据库,我在ASP.NET MVC 3/C#中使用实体框架代码优先,但我收到错误.在我的Event类中,我有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; }
}
Run Code Online (Sandbox Code Playgroud)
控制器中的方法>>>> 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);
}
}
Run Code Online (Sandbox Code Playgroud)
同
public class EventCalendarEntities : DbContext
{
public DbSet<Event> Events { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Place> Places { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
SQL Server 2008 R2数据库/ T-SQL
EventDate (Datatype = date)
StartTime (Datatype = time)
EndTime (Datatype = time)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
'/'应用程序中的服务器错误.
一个或多个实体的验证失败.有关详细信息,请参阅"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: }
Run Code Online (Sandbox Code Playgroud)
源文件:C:\ sep\MvcEventCalendar\MvcEventCalendar\Controllers\EventManagerController.cs行:77
堆栈跟踪:
[DbEntityValidationException:一个或多个实体的验证失败.有关详细信息,请参阅"EntityValidationErrors"属性.
Pra*_*sad 838
您可以提取所有从信息DbEntityValidationException用下面的代码(你需要添加命名空间:System.Data.Entity.Validation和System.Diagnostics你的using列表):
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
GON*_*ale 249
无需更改代码:
当您处于catch {...}块内的调试模式时,打开"QuickWatch"窗口(Ctrl+ Alt+ Q)并粘贴到那里:
((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors
Run Code Online (Sandbox Code Playgroud)
要么:
((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors
Run Code Online (Sandbox Code Playgroud)
如果您不在try/catch中,或者无法访问异常对象.
这将允许您深入到ValidationErrors树中.这是我发现能够即时了解这些错误的最简单方法.
Ton*_*ony 37
如果你有具有相同属性名称的类,这里是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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Bol*_*der 22
作为对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...
}
}
}
Run Code Online (Sandbox Code Playgroud)
此实现将实体异常包装到具有详细文本的异常.它处理DbEntityValidationException,DbUpdateException,datetime2范围错误(MS SQL),并且包括在消息无效实体的关键(有用的一个savind许多实体时SaveChanges调用).
首先,SaveChanges在DbContext类中重写:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我遇到Entity VAlidation Erros问题时,此代码帮助我找到了问题.它告诉我我的实体定义的确切问题.尝试使用以下代码来覆盖storeDB.SaveChanges(); 在下面尝试catch块.
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;
}
Run Code Online (Sandbox Code Playgroud)