2014-01-12 165 views
1

我在實體框架中的映射遇到了一些麻煩。我有一張表格Check,它有一個CheckStatusHistory表格的外鍵,用於存儲所有檢查狀態隨時間的變化。正如你所看到的,Check有一個LastCheckStatusID列,它的FK爲CheckStatusHistoryID,但CheckStatusHistory表也具有CheckID作爲FK到Check的CheckID列。 這個想法是將最後一個CheckStatusHistoryID存儲在檢查中,以便更容易地獲得最後檢查狀態並獲得更好的性能。而且,也有所有的歷史信息。UpdateException實體框架雙向外鍵

然後,當我從數據庫生成實體框架實體我得到這個圖:

enter image description here

的一個,它的*(從檢查)至1(CheckStatusHistory),應該是1比1。但是這對EF的限制是不可能的。

然後,在我的代碼,當我想創建一個具有歷史地位的支票,我做的:

Check newCheck = new Check 
       { 
        Amount = c.Amount, 
        CheckDate = c.CheckDate, 
        CheckNumber = c.CheckNumber, 
        CheckPrefix = c.CheckPrefix, 
        Days = c.Days, 
        Expenses = c.Expenses, 
        RoutingNumbers = c.RoutingNumbers, 
        TradeHours = c.TradeHours, 
        TotalInterest = c.TotalInterest, 
        TentativeDepositDate = c.TentativeDepositDate, 
        TentativeAccreditationDate = c.TentativeAccreditationDate, 
        MonthlyRate = c.MonthlyRate 
       }; 

newCheck.CheckStatusHistory = new CheckStatusHistory 
       { 
        CheckStatusID = CheckStatusIDs.Nuevo, 
        StatusDateTime = DateTime.Now, 
       }; 

這應該被添加在[CheckStatusHistory]一行。這個newCheck.CheckStatusHistory是與LastCheckStatusID相關的CheckStatusHistory。

但是當我做db.SaveChanges()。

我得到以下錯誤:

System.Data.Entity.Infrastructure.DbUpdateException was unhandled by user code 
    HResult=-2146233087 
    Message=Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values. 
    Source=EntityFramework 
    StackTrace: 
     en System.Data.Entity.Internal.InternalContext.SaveChanges() 
     en System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
     en System.Data.Entity.DbContext.SaveChanges() 
     en Plutus.Services.Check.CreateOperationHandler.Handle(CreateOperationRequest request) en e:\Plutus\Plutus.Services\Plutus.Services\Check\CreateOperationHandler.cs:línea 169 
     en Plutus.Services.RequestResponse.RequestResponseFactory.Handle[TRequest,TResponse](TRequest request) en e:\Plutus\Plutus.Services\Plutus.Services\RequestResponse\RequestResponseFactory.cs:línea 48 
     en Plutus.Services.Host.CheckService.CreateOperation(CreateOperationRequest request) en e:\Plutus\Plutus.Services\Plutus.Services.Host\CheckService.svc.cs:línea 50 
     en SyncInvokeCreateOperation(Object , Object[] , Object[]) 
     en System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) 
     en System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) 
    InnerException: System.Data.Entity.Core.UpdateException 
     HResult=-2146233087 
     Message=Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values. 
     Source=EntityFramework 
     StackTrace: 
      en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.DependencyOrderingError(IEnumerable`1 remainder) 
      en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() 
      en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() 
      en System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut) 
      en System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction, Boolean throwOnClosedConnection) 
      en System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update(Boolean throwOnClosedConnection) 
      en System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__33() 
      en System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
      en System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy) 
      en System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass28.<SaveChanges>b__25() 
      en System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
      en System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) 
      en System.Data.Entity.Internal.InternalContext.SaveChanges() 
     InnerException: 

我覺得這可能是一個具有2 FK,一個從一個表到其他相關的,另一個是最後一個表格的第一。

我需要一些幫助。

我離開這裏的SQL表:

CREATE TABLE [dbo].[Check](
     [CheckID] INT PRIMARY KEY IDENTITY NOT NULL, 
     [RoutingNumbers] NCHAR(29) NOT NULL, 
     [BankID] INT NOT NULL, --FK 
     [BankBranchOfficeID] INT NOT NULL, -- FK 
     [BankAccountID] INT NOT NULL, 
     [CheckPrefix] NVARCHAR(3) NOT NULL, 
     [CheckNumber] NCHAR(7) NOT NULL, 
     [CheckDate] DATE NOT NULL, 
     [Amount] MONEY NOT NULL, 
     [TentativeDepositDate] DATE NOT NULL, 
     [TradeHours] INT NOT NULL, 
     [TentativeAccreditationDate] DATE NOT NULL, 
     [Expenses] MONEY NULL, 
     [MonthlyRate] DECIMAL (6,2) NOT NULL, 
     [TotalInterest] MONEY NOT NULL, 
     [Days] INT NOT NULL, 
     [LastCheckStatusID] INT NOT NULL, 
     [OperationID] INT NOT NULL,--FK 
     CONSTRAINT FK_Check_BankID_Bank FOREIGN KEY ([BankID]) REFERENCES [dbo].[Bank]([BankID]), 
     CONSTRAINT FK_Check_BankBranchOfficeID_BankBranchOffice FOREIGN KEY ([BankBranchOfficeID]) REFERENCES [dbo].[BankBranchOffice]([BankBranchOfficeID]), 
     CONSTRAINT FK_Check_BankAccountID_BankAccount FOREIGN KEY ([BankAccountID]) REFERENCES [dbo].[BankAccount]([BankAccountID]), 
     CONSTRAINT FK_Check_CheckStatusHistoryID_CheckStatusHistory FOREIGN KEY (LastCheckStatusID) REFERENCES [dbo].[CheckStatusHistory]([CheckStatusHistoryID]), 
     CONSTRAINT FK_Check_OperationID_Operation FOREIGN KEY ([OperationID]) REFERENCES [dbo].[Operation]([OperationID]) 
     ) 

    /*--------------------------------------------------------------- 
     ESTADO DE CHEQUES 
    */--------------------------------------------------------------- 
    CREATE TABLE [dbo].CheckStatus(
     [CheckStatusID] TINYINT PRIMARY KEY, 
     [Name] NVARCHAR(30) NOT NULL 
    ) 

    /*--------------------------------------------------------------- 
     RELACION ESTADO - CHEQUE 
    */--------------------------------------------------------------- 

     CREATE TABLE [dbo].[CheckStatusHistory](
     [CheckStatusHistoryID] INT PRIMARY KEY IDENTITY, 
     [CheckStatusID] TINYINT NOT NULL, --FK 
     [CheckID] INT NOT NULL, 
     [StatusDateTime] DATETIME NOT NULL 
     CONSTRAINT FK_CheckStatusHistory_CheckID_Check FOREIGN KEY ([CheckID]) REFERENCES [dbo].[Check]([CheckID]), 
     CONSTRAINT FK_CheckStatusHistory_CheckStatusID_CheckStatus FOREIGN KEY ([CheckStatusID]) REFERENCES [dbo].[CheckStatus]([CheckStatusID]) 
    ) 

回答

1

是的,它是與兩個FKS。 EF使用該模型創建DB命令的排序。它不會檢查您設置的數據。它試圖找到一種在每種情況下都能正常工作的順序 - 這種順序在您的情況下不存在,因爲您的模型允許創建兩條記錄(每個表中一條記錄),這兩條記錄將相互依賴。在這種情況下,不可能一次插入它們。在數據庫級別上,您只需插入第一個沒有依賴關係的第二個,第二個依賴項插入第一個,然後將第一個依賴項更新爲第二個。 EF不以這種方式工作。

其他人可能不同意,但隨着時間的推移,我得出的結論是,歷史表最好的作品沒有受到不同的參考約束限制。例如,允許保留從主表中刪除的數據的歷史記錄。你需要從StatusHistory的FK來檢查嗎?即使您沒有FK,您仍然可以存儲CheckID並執行手動Linq查詢以獲取Check的歷史記錄,但是您將丟失導航屬性屬性。

+0

謝謝你的回答!無論如何,我解決了它,但我認爲這可以幫助別人。我最終以兩步完成了交易。 – Andres