顯示具有 Entity Framework 標籤的文章。 顯示所有文章
顯示具有 Entity Framework 標籤的文章。 顯示所有文章

Problem Using INSTEAD OF Triggers with Entity Framework

0 comments
若你在使用識別資料行做為主索引鍵的資料表中,定義 INSTEAD OF INSERT 觸發程序,並透過 ObjectContext 的 SaveChanges 方法新增資料時,將會引發 OptimisticConcurrencyException,並導致整個交易復原。以下是發生例外狀況的錯誤訊息:
存放區更新、插入或刪除陳述式影響到非預期數目的資料列 (0)。這些實體載入之後可能被修改或刪除了。請重新整理 ObjectStateManager 實體。

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

如以下範例,會依據 AdventureWorks 實體資料模型的定義,將新的實體物件附加到物件內容:
using (AdventureWorksEntities context = new AdventureWorksEntities()) 
{
context.AddToSalesReason(new SalesReason() {
Name = "Recommendation", ReasonType = "Other", ModifiedDate = DateTime.Now
});
context.SaveChanges();
}

當呼叫 SaveChanges 方法時,物件服務會產生及執行以下 SQL 命令:
exec sp_executesql N'insert [Sales].[SalesReason]([Name], [ReasonType], [ModifiedDate])
values (@0, @1, @2)
select [SalesReasonID]
from [Sales].[SalesReason]
where @@ROWCOUNT > 0 and [SalesReasonID] = scope_identity()
'
,N'@0 nvarchar(14),@1 nvarchar(5),@2 datetime2(7)'
,@0=N'Recommendation',@1=N'Other',@2='2009-11-02 15:14:54.4856524'

因為該實體物件包含識別插入的實體索引鍵,所以會在 INSERT 陳述式後,搭配使用 SCOPE_IDENTITY 函數以取得插入識別欄位中的最後一個識別值。然而,如果此資料表已定義 INSTEAD OF INSERT 觸發程序,則 SCOPE_IDENTITY 函數會因為分屬不同的範圍(Scope)而傳回 NULL 值,於是導致 SaveChanges 失敗,而復原該筆交易並擲回如前述的 OptimisticConcurrencyException 例外狀況。

要解決這個問題,你可以使用預儲程序取代 INSTEAD OF INSERT 觸發程序,然後利用實體資料模型設計工具(Entity Designer),把實體類型的修改函式對應至預存程序。或者,你也可以使用 ExecuteCommand 擴充方法來直接執行新增作業的預儲程序。

繼續閱讀...

How to Fix "Unable to update the EntitySet" Error

0 comments
如果你嘗試對資料表實體集進行新增、修改、刪除資料時,有可能會發生無法更新實體集的例外狀況。以下是更新資料時所引發的錯誤訊息:
System.Data.UpdateException: 無法更新 EntitySet '實體集名稱',因為它有 DefiningQuery,但是在 <ModificationFunctionMapping> 項目中沒有 <UpdateFunction> 項目來支援目前的作業。

Unable to update the EntitySet 'EntitySet Name' because it has a DefiningQuery and no <UpdateFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.

當你將不含主索引鍵的資料表加入實體資料模型(Entity Data Model,EDM)時,Entity Framework 會因為找不到資料表主索引鍵,而將定義建立成唯讀的資料表,也就是在描述儲存結構之 SSDL 區段所定義的 EntitySet 項目中,加入 DefiningQuery 項目以對應到資料存放區的唯讀檢視。所以,當實體集使用定義查詢時,你就無法使用標準更新處理序將保存更新至資料來源。如果嘗試對唯讀的實體集進行更新動作,將會引發如上所述的例外狀況。

要解決這個問題,你可以為來源資料表加入主索引鍵,並透過更新資料庫模型來獲得解決。或者,你也可以利用實體資料模型支援使用預儲程序的功能,定義插入、更新、刪除函式對應來進行資料更新。

繼續閱讀...