かなり興味深い例外が発生しています。昨日、過去のある時点で機能していたコードで発生しました(私はコードベースのほとんどを継承し、以前の開発者はもう私たちと一緒にいません)。
昨日を使用して回避策を適用しました.Where()
が、今日は別のコントローラーで再び問題が発生したため、予期しない場所に噛み付く前に、その問題の根底に到達するのが最善であると判断しました。
以下のエラーが発生します:
参照整合性制約違反が発生しました:参照整合性制約の一部である主キープロパティは、関連付けの主オブジェクトに設定されていない限り、依存オブジェクトが変更されていない場合は変更できません。主要なオブジェクトは追跡され、削除のマークが付けられていない必要があります。
さて、奇妙な部分です。DbContext.DbSet.Find(int)
新しいdbContextでFind()メソッドを使用すると、このエラーが発生します。
正確なコードは次のとおりです。5行目でCurResponseオブジェクトを問題なく検出しますが、失敗し、db.CurFundings.Find(post.SelectedSourceCurFundingKey);
以下の7行目で検出されると上記の例外をスローします。
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);
そして、私はまだ上記のエラーを受け取ります。
クイックウォッチすると、3つのオブジェクトが返され、そのうちの1つに1_db.CurFundings
の主キーがあります。
クイックウォッチする 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からアイテムを取得する場合にのみ発生します。
私はEFCodeFirstを使用していますが、現在のコードの大部分は数か月前に継承されました。
これが役立つかどうかはわかりませんが、この特定のオブジェクトを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