DbContext.Find()(代码优先)上发生了引用完整性约束冲突

时间:2013-01-11 20:11:49

标签: c# entity-framework dbcontext invalidoperationexception

我遇到了一个相当有趣的例外。昨天发生的代码在过去的某个时刻起作用了(我继承了大部分代码库,前开发人员不再和我们在一起了)。

我昨天使用.Where()应用了一个解决方法,但是因为我今天在另一个控制器中再次遇到了这个问题,所以我决定最好先找到它的底部然后把它咬到我意想不到的地方。

我收到以下错误:

  

发生了参照完整性约束违规:主键   作为参照完整性约束的一部分的属性不能   除非正在设置,否则在依赖对象未更改时更改   该协会的主要对象。主要对象必须是   跟踪并且没有标记为删除。

现在为了奇怪的部分。当我使用Find()方法DbContext.DbSet.Find(int)和新的dbContext时,我收到此错误。

这是确切的代码。它在第5行找到了CurResponse对象而没有发生意外,但它失败并在遇到下面第7行的db.CurFundings.Find(post.SelectedSourceCurFundingKey);时抛出上面的异常:

0. [HttpPost]
1. public ActionResult MatchingCur2Fundings(int id, MatchingCur2FundingsVM post, string callbackId)
2. {
3. if (ModelState.IsValid)
4. {
5. var cur = _db.CurResponses.Find(id);
6. var c2f = new Cur2FundingDataFlow();
7. c2f.SourceFunding =  _db.CurFundings.Find(post.SelectedSourceCurFundingKey);

我用下面的整数替换post.SelectedSourceCurFundingKey

7. c2f.SourceCurFunding = _db.CurFundings.Find(1);

我仍然得到上面的错误。

当我快速观察_db.CurFundings时,它会返回3个对象,其中一个对象的主键为 1

当我快速观察db.CurFundings.Find(post.SelectedSourceCurFundingKey);时,我得到上面的错误,所以它与作业左侧的内容没有任何关系。

我可以将DbContext.DbSet.Find()替换为DbContext.DbSet.Where(x => x.id == id).SingleOrDefault()来获取我需要的项目,如下所示:

c2f.SourceCurFunding = _db.CurFundings.Where(cf => cf.CurFundingKey == post.SelectedSourceCurFundingKey).SingleOrDefault();

仅当我使用Find()方法从DbContext检索项目时才会出现此问题。

我正在使用EF CodeFirst,并且几个月后继承了大部分当前代码。

我不知道这是否会有所帮助,但这里是将此特定对象添加到我的DbContext的行:

public DbSet<CuFunding> CurFundings { get; set; }

这是对应用程序中DbContext.CurFundings属性的唯一引用,当我查看该类型的用法时,我看不到任何奇怪的事情。

我总是可以使用.Where()来获得我需要的东西,但我想确保这不是更深层次问题的迹象。

编辑1

以下是整个CurFunding类,它实际上是CurConstructionFunding,但我缩短了上一个示例中的名称:

namespace MfpSuite.Models.Documents.CUR
{
  public class CurConstructionFunding
  {
    [Key]
    public int CurConstructionFundingKey { get; set; }
    public int CurPropertyKey { get; set; }
    [ForeignKey("CurPropertyKey")]
    public virtual CurProperty CurProperty { get; set; }

    public string Source { get; set; }
    public string Lender { get; set; }
    public string ConstructionAmount { get; set; }
    public string PermanentAmount { get; set; }
    public string PermanentLoanPerUnit { get; set; }
    public string TotalConstructionAmount { get; set; }
    public string TotalPermanentAmount { get; set; }
    public string TotalPermanentLoanPerUnit { get; set; }

    //public int CurResponseKeyId { get; set; }
    //[ForeignKey("CurResponseKeyId")]
    //public virtual CurResponse CurResponse { get; set; }

    /// <summary>
    /// Indicates which funding this data is imported into.  Note there shouldn't be more than one item in this collection.
    /// 01/14/13 - todo - if there shouldn't be more than one, this should be a 1|1 mapping here (like we have [mistakenly] done w/ docTypes to Doc)
    /// </summary>
    public virtual ICollection<Cur2FundingDataFlow> Cur2FundingDataFlow { get; set; }

  }
}

编辑2

以下是我可以从Find()的快速监视器中获取的内容:

_db.CurConstructionFundings = {SELECT 
[Extent1].[CurConstructionFundingKey] AS [CurConstructionFundingKey], 
[Extent1].[CurPropertyKey] AS [CurPropertyKey], 
[Extent1].[Source] AS [Source], 
[Extent1].[Lender] AS [Lender], 
[Extent1].[ConstructionAmount] AS [ConstructionAmount], 
...

_db.CurConstructionFundings

{SELECT 
[Extent1].[CurConstructionFundingKey] AS [CurConstructionFundingKey], 
[Extent1].[CurPropertyKey] AS [CurPropertyKey], 
[Extent1].[Source] AS [Source], 
[Extent1].[Lender] AS [Lender], 
[Extent1].[ConstructionAmount] AS [ConstructionAmount], 
[Extent1].[PermanentAmount] AS [PermanentAmount], 
[Extent1].[PermanentLoanPerUnit] AS [PermanentLoanPerUnit], 
[Extent1].[TotalConstructionAmount] AS [TotalConstructionAmount], 
[Extent1].[TotalPermanentAmount] AS [TotalPermanentAmount], 
[Extent1].[TotalPermanentLoanPerUnit] AS [TotalPermanentLoanPerUnit]
FROM [dbo].[CurConstructionFundings] AS [Extent1]}

        StackTrace  "   at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)\r\n   
        at System.Data.Objects.ObjectStateManager.DetectChanges()\r\n   
        at System.Data.Objects.ObjectContext.DetectChanges()\r\n   
        at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)\r\n   
        at System.Data.Entity.Internal.Linq.InternalSet`1.Find(Object[] keyValues)\r\n  
        at System.Data.Entity.DbSet`1.Find(Object[] keyValues)" string

        +       [System.Reflection.RuntimeMethodInfo]   {Void DetectConflicts(System.Collections.Generic.IList`1[System.Data.Objects.EntityEntry])} System.Reflection.RuntimeMethodInfo

0 个答案:

没有答案