实体框架6更新外键引用NULL的位置

时间:2016-05-21 01:52:14

标签: c# asp.net-mvc entity-framework linq

我有一个表DivorceCases,它有很多字段,它的模型如下:

    [Key]
    [Required]
    public string case_id { get; set; }
    public string user_id { get; set; }
    public DateTime case_date { get; set; }
    public virtual Transactions t { get; set; }

我正在尝试将事务详细信息添加到现有行,但我得到[NullReferenceException:对象引用未设置为对象的实例。]错误。在DivorceCases表中,EF6为事务表的外键引用创建了一个列t_id。

Observable.catch()

我用过:

public static void UpdatePayment(string cid,string txnno)
  {
 DivorceCasesContext db = new DivorceCasesContext();
            DivorceCases dc = db.DivorceCase.Where(x => x.case_id == cid).Include(x => x.t).SingleOrDefault();
            if (dc.t == null || dc.t.txn_id1 == null || dc.t.txn_id1 == "")
            {
                dc.t.txn_id1 = txnno;
                dc.t.amount1 = amount.ToString();
                dc.t.date1 = DateTime.Now.ToString();
            }
            else
            {
                dc.t.txn_id2 = txnno;
                dc.t.amount2 = amount.ToString();
                dc.t.date2 = DateTime.Now.ToString();
            }
            db.Set<DivorceCases>().Attach(dc);
            db.Entry(dc).State = EntityState.Modified;
            db.SaveChanges();
        }
}

我得到的错误是:

    [NullReferenceException: Object reference not set to an instance of an object.]
   gonylaw.Helpers.Amounts.UpdatePayment(String cid, String txnno) +425
   gonylaw.Controllers.PaymentController.PaymentProcessor(CreditCard c) +461
   lambda_method(Closure , ControllerBase , Object[] ) +104
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9644037
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

1 个答案:

答案 0 :(得分:2)

您正在访问dc.t的属性,而不确保dc.t不为空。如果第一个条件if语句短路,dc.t为空,但您尝试将值分配给dc.t.txn_id

if( dc.t == null || ... )
{
    dc.t.txn_id1 = txnno; // null ref exception here
}

请注意,我建议还有其他改进措施:

public static void UpdatePayment(string cid,string txnno)
{
    // add using block to dispose of DbContext after you're done with it
    using( DivorceCasesContext db = new DivorceCasesContext() )
    {
        DivorceCases dc = db.DivorceCase.Include(x => x.t)
            .Where( x => x.case_id == cid )
            .SingleOrDefault();

            // take care of your null ref problem
            if( dc.t == null )
            {
                dc.t = new Transactions();
            }

            // simplify null/empty string check
            if( string.IsNullOrEmpty( dc.t.txn_id1 ) )
            {
                dc.t.txn_id1 = txnno;
                dc.t.amount1 = amount.ToString();
                dc.t.date1 = DateTime.Now.ToString();
            }
            else
            {
                dc.t.txn_id2 = txnno;
                dc.t.amount2 = amount.ToString();
                dc.t.date2 = DateTime.Now.ToString();
            }

            // this is not needed - dc is already attached to the context
            //  (unless you're doing something nonstandard by default
            //   within your DbContext)
            //db.Set<DivorceCases>().Attach(dc);
            //db.Entry(dc).State = EntityState.Modified;

            db.SaveChanges();
        }
    }
}