简体   繁体   English

EF为什么在这里抛出异常?

[英]Why does EF throw an exception here?

Ok i'm going nuts here, I have been trying to write myself an update method in my repository and for some strange reason I get an exception when I call this ... 好的,我在这里疯了,我一直在尝试向自己的存储库中编写一个更新方法,由于某种奇怪的原因,当我调用此方法时,我得到了一个异常...

public virtual T Update(T entity)
{
    T dbEntity = _context.Set<T>().Find(entity.GetId());

    if (dbEntity != null)
    {
        _context.SaveChanges();
    }

    return dbEntity;
}

The exception occurs on "_context.SaveChanges();", context in this case is a DbContext instance as opposed to an object context. 异常发生在“ _context.SaveChanges();”上,在这种情况下上下文是DbContext实例,而不是对象上下文。 I'm using EF code first and the of T is as follows ... 我首先使用EF代码,T的如下所示...

public partial class AC_Programme
{
    [Key]
    public int Id { get; set; }

    public int OrganisationId { get; set; }

    [Required]
    [StringLength(255)]
    public string Name { get; set; }

    public string Description { get; set; }

    public DateTime Start { get; set; }

    public DateTime End { get; set; }

    public bool Active { get; set; }

    [DataType(DataType.Time)]
    public DateTime AutoCalculationTime { get; set; }

    [DataType(DataType.Time)]
    public DateTime AutoCutoffTime { get; set; }

    public virtual ICollection<AC_Fund> AC_Funds { get; set; }

    public virtual CX_Organisation Organisation { get; set; }
}

I can't understand why despite having done literally nothing, all I did was retrieve an object by id and call save changes, that it feels the need to go messing with relationships. 我不明白为什么尽管实际上什么也没做,但我所做的只是通过id检索对象并调用save更改,感觉需要弄乱关系。

Any Ideas? 有任何想法吗?

EDIT: oops I forgot to include the exception ... 编辑:哎呀,我忘了包括异常...

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code EntityFramework.dll中发生类型'System.InvalidOperationException'的异常,但未在用户代码中处理

Additional information: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. 附加信息:操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。 When a change is made to a relationship, the related foreign-key property is set to a null value. 对关系进行更改时,相关的外键属性将设置为空值。 If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted. 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

It gets even more peculiar ... 它变得更加独特...

    public virtual T Update(T entity)
    {
       _context.SaveChanges();
        return null;
    }

... results in the same error. ...导致相同的错误。

Looking at the exception I'm assuming you forgot to set the value of a property which is part of a foreign key constraint; 在查看异常时,我假设您忘记设置作为外键约束一部分的属性的值。 maybe OrganizationId ? 也许OrganizationId

Another possibility is that you removed a child entity from AC_Funds property and did not mark the child as deleted. 另一种可能性是您从AC_Funds属性中删除了一个子实体,并且没有AC_Funds标记为已删除。 This would result in an orphaned child which means setting the foreign key property to a null value. 这将导致一个孤立的子代,这意味着将外键属性设置为空值。

Since your foreign key does not allow nulls the child entity cannot be orphaned and must be deleted. 由于您的外键不允许为null,因此无法孤立子实体,必须将其删除。

I would suggest opening the Sql Server Profiler and peeking at the update statements generated by Entity Framework. 我建议打开Sql Server Profiler并查看由Entity Framework生成的更新语句。

The problem was that some code further up the stack was adding changes in to EF that should not have been there causing this problem. 问题是堆栈上的某些代码正在向EF中添加本不应该引起此问题的更改。

Diagnosing this problem was possible by putting a breakpoint on the SaveChanges call and examining "_context.ChangeTracker.Entries()" for changes then looking through the call stack to see what was going on. 通过在SaveChanges调用上放置一个断点并检查“ _context.ChangeTracker.Entries()”进行更改,然后查看调用堆栈以查看发生了什么,可以诊断该问题。

Depending on the complexity of your own code if faced with this you may find it beneficial to add the change tracker to the watch window then step through the code until a change appears. 根据您自己的代码的复杂性,如果遇到这种情况,您可能会发现将更改跟踪器添加到监视窗口,然后逐步执行代码直到出现更改,这将是有益的。

Thanks for the advice @JohnnyHK 感谢@JohnnyHK的建议

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM