【问题标题】:SaveChanges() from an EntityFramework context fails silentlyEntityFramework 上下文中的 SaveChanges() 静默失败
【发布时间】:2014-06-30 21:46:41
【问题描述】:

我正在使用来自数据库“向导”设置的实体框架 6.1 模型。 当我从我的上下文创建一个业务对象,然后尝试添加附件,然后 SaveChanges() 没有任何反应。有追踪模式吗?或者我可以打开以查看幕后实际发生的事情。

简单示例:

 var fb = _context.Business.Create();
 //fb.Id exists and is an int but it is auto incr in the db
 fb.Name = ub.ACCOUNT_NAME;
 fb.ServiceManager = ub.SERVICE_MANAGER;
 fb.AccountManager = ub.ACCOUNT_MANAGER;
 fb.SalesPerson = ub.SALESPERSON;
 fb.Created = DateTime.UtcNow;
 fb.Updated = DateTime.UtcNow;
 _context.Add(fb);
 _context.SaveChanges();

【问题讨论】:

  • 你确定它是静默失败吗?您是否尝试过设置断点并调用 _context.GetChangeSet() ?
  • 它是什么应用类型? WinForms\Web?你说它失败是什么意思?插入的记录后面不存在?
  • 使用 sql Profiler 查看数据库中正在执行的操作。
  • hm,那我也同意@Ezi,你需要使用SQL Profiler来验证它在SaveChanges调用期间是否在SQL服务器端执行任何SQL查询。
  • @BuddyJoe 您的 SQL Trace 显示了什么?

标签: c# .net entity-framework entity-framework-6


【解决方案1】:

我发现捕获 EF 错误的最佳方法是重写 SaveChange 方法,如下所示。如果您有一个中心位置来恢复日志(如 log4net),该函数将能够将其插入那里。

public partial class Business
{
    /// <summary>Override the SaveChange to return better error messages</summary>
    public override int SaveChanges()
    {
        try {
            return base.SaveChanges();
        }
        catch (System.Data.Entity.Validation.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);

            // Add some logging with log4net here


            // Throw a new DbEntityValidationException with the improved exception message.
            throw new System.Data.Entity.Validation.DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);

        }
    }

【讨论】:

    【解决方案2】:

    您是否尝试过检查任何验证错误?

    这是我在我的一个新类中使用的 try 块和验证方法,因此请将其视为代码示例,而不是 100% 测试的解决方案,因为我仍在整理一些单元测试:

    public List<string> ValidationErrorList = new List<string>();
    
    
    try
    {
      _context.SaveChanges();
    }
    catch (Exception)
    {
      GetErrors(_context);
    }
    
    private void GetErrors(System.Data.Entity.DbContext context)
    {
    
      IEnumerable<System.Data.Entity.Validation.DbEntityValidationResult> ve;
    
      ve = context.GetValidationErrors();
      ValidationErrorList.Clear();
    
      foreach (var vr in ve)
      {
        if (vr.IsValid == false)
        {
          foreach (var e in vr.ValidationErrors)
          {
            var errorMessage = e.PropertyName.Trim() + " : " +
                               e.ErrorMessage;
            ValidationErrorList.Add(errorMessage);
          }
        }
      }
    }
    

    虽然上述示例仅在触发异常时调用 GetErrors 方法,但您可能还想尝试在 SaveChanges() 之后立即调用它,以查看是否存在未引发异常的验证错误。

    【讨论】:

      【解决方案3】:

      您是否尝试过创建一个新的业务对象并将其添加进去?而不是先创建一个?

       var fb = new Business();
       //fb.Id exists and is an int but it is auto incr in the db
       fb.Name = ub.ACCOUNT_NAME;
       fb.ServiceManager = ub.SERVICE_MANAGER;
       fb.AccountManager = ub.ACCOUNT_MANAGER;
       fb.SalesPerson = ub.SALESPERSON;
       fb.Created = DateTime.UtcNow;
       fb.Updated = DateTime.UtcNow;
       _context.Business.Add(fb);
       _context.SaveChanges();
      

      【讨论】:

      • 那么 Create 和 new 有什么区别?
      猜你喜欢
      • 2020-01-26
      • 2015-10-03
      • 2017-08-03
      • 1970-01-01
      • 2017-01-10
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多