2010-01-22 101 views
3

我有一個MVC2應用程序,我開始使用STE的。我正在尋找關於更新應該如何工作的一些說明。自我跟蹤實體(STE)和EF4和mVC2的部分更新

背景:

如果我有相關的類別實體和相關崗位/評論實體博客實體。在MVC中,我使用主Blog實體和類別呈現視圖,但不顯示相關帖子。當我將博客實體回發到服務器時,我可以看到相關類別,但是在被序列化回服務器的實體中看不到帖子(因爲它們不在視圖中)。此外,博客實體的更改狀態爲「已添加」。

然後我嘗試撥打此博客實體上的Applychanges()SaveChanges()來執行更新,並且由於FK與帖子的關係以及數據庫中存在相關帖子但未附加到實體的事實而失敗送回。

隨着一些進一步的測試...如果我連接到服務器(狀態=不變)時抓取博客實體的當前實例(與所有相關的FK實體),修改一個屬性(狀態=修改)並更新它按預期工作。

所以我的問題: 如果我有相關的未被呈現在視圖中,因此不回來後與博客實體應該更新實體機構開展工作?

爲什麼博客實體會以「已添加」狀態發回而不是「已修改」?我會假設它會返回所有已更改實體的「修改」更改狀態,然後當我調用ApplyChanges/SaveChanges()時,只有修改的項目會嘗試更新,這就是爲什麼我不需要所有相關實體的原因。

我應該能夠直接從客戶端傳遞實體,還是應該將實體回傳給服務器,從數據庫中抓取現有副本,將更改應用到該副本,然後將現有對象發回?

回答

1

關於你的第一個問題:

然後我試圖在這個博客上實體調用Applychanges()和 的SaveChanges()來 的執行更新,也未能 因爲 的FK關係帖子和數據庫中有 相關帖子,但不是 附加到我發送 回來的實體。

這可能是由您的第二個問題(「已添加」狀態而不是「已修改」)引起的。上下文可能試圖添加博客而不是試圖保存更改,因此FK約束錯誤。

至於你的第二個問題:

爲什麼「修改」博客實體GET後回 與「新增」狀態,而不是

?我相信它會 回來了「修改」 changedstate所有更改的實體 ,然後當我打電話 ApplyChanges /調用SaveChanges()只有 修改的項目將嘗試更新 ,這就是爲什麼我不需要所有 相關實體。

是「您使用的生成服務器和客戶端代碼相同的類型」來考慮問題?當您使用數據服務元數據生成類型時,STE已經爲known to not keep track of changes。對於STE,有一段代碼在構造函數中被激活,不會持續通過元數據生成的類型,因此是導致此問題的原因。

至於你最後quesiton:

我應該可以直接從客戶端傳遞一個實體 和 ApplyChanges()/調用SaveChanges(),還是應該 我要回發到服務器 實體,從 數據庫中抓取現有的副本,將該更改應用到 副本,然後發佈現有的 對象?

是的,這是可能的(我已經測試了這一點),以ApplyChanges()/調用SaveChanges()直接來自客戶端,無論在哪裏實體最初是從(從服務器傳來的實體進行修改或創建在客戶端上作爲新的實體添加)。

+0

我打算將此標記爲答案,因爲您確實提供了一些相關的良好反饋。但總體回答是,這不會像我預期的那樣使用MVC。我收到了迭戈維加在EF小組解釋原因的回覆。這裏是他的迴應鏈接: http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/cecdc8b4-3e1f-46ec-93fe-fd44f42fea9c/#fb8a242b-c8f2-4ac2-a28c- 4b948cac8c8c – Jay 2010-03-10 14:37:39

0

我們非常相似的問題 - 周圍的更新掙扎。根據我們的信息,我們收集到STE尚未準備好生產,但確實考慮過使用它們。

無論如何,這裏的問題集中在附加和分離之間的區別,以及ObjectStateManager和STE之間的相互作用......在你描述的那個例子中,它起作用,因爲它一直附着在STE上,從未實際轉換到使用其STE行爲(這隻發生在反序列化到客戶端之後,或者它們被重新連接到連接的實體)。

在回答他們爲什麼顯示爲補充:

例如,當國營被實例化,更改跟蹤被停用,並在變更跟蹤器的默認狀態添加。

我發現這一切令人困惑,並採訪了Julia Lerman,並在線發帖,似乎表明目前的STE版本還沒有準備好現實世界......

見迭戈維加(EF隊)這種反應

當您在此模式下使用國營貿易公司,他們大致表現爲純POCO對象。例如,您可以直接操作圖形或使用ObjectContext和ObjectStateManager中的API,並且必須調用DetectChanges以確保在調用SaveChanges之前狀態管理器在任何時刻都與圖形同步。

最重要的是,標準對象服務API不知道STE,因此,諸如AcceptAllChanges(在您的示例中,它在SaveChanges期間隱式調用,並將投訴對象的ObjectStateManager狀態重置爲Unchanged)絕對不會影響國有企業儲存的國家。

http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/557e6db0-51df-45e5-a2e9-c31995969554

希望這有助於

+0

@Bobby謝謝,我看過同一篇文章迭戈當我昨天正在研究。但他表示:「只有在以下情況下,STEs纔會進入自我跟蹤模式:a。它們被反序列化到客戶端中......」這對我而言意味着當對象從我的WCF服務中拉出並反序列化到客戶端時,它應該開始跟蹤模式。這應該將其置於UnModified狀態。我沒有看到使用STE的好處,如果它不爲我做。它只是提供了一些額外的狀態跟蹤(它並不適用於無狀態環境:) – Jay 2010-01-22 17:36:44

0

我不認爲我曾經說,國營貿易公司還沒有準備好真實的世界。他們不會適合每個人。對於那些只需要能夠輕鬆工作的數據集/數據表用戶而言,它們是一款相當不錯的工具。對於這些用戶(他們中有很多人)將STE實體放入客戶端應用程序中並不是什麼壞事。這可能已經擁有了管道的兩面。

+0

嘿,朱莉,歡迎來到Stack Overflow。我發現你的書是非常有用的,即使它不包含EF 4(STE等),它仍然適用於所有EF概念。 – 2010-02-28 10:50:25

+0

那麼,當簡單的解決方案到位時,爲什麼我們會以困難的方式做事。 – ashraf 2010-03-23 19:59:01

1

我對此的觀察是,雖然EF4中的STE在客戶端爲有狀態的情況下運行良好,但在無狀態環境中,它們無法按預期工作。

MVC強調了這個缺點。例如,讓我們看一個典型的實體「用戶」和一個典型的場景,EditController和Edit視圖。當我們訪問我們的數據庫(獲取用戶,開始跟蹤,返回)或我們的服務(反序列化後自動啓用更改跟蹤)時,實體在控制器和視圖內按預期行爲。

但是,當郵政回來時,我們的Controller方法得到的實體是一個新的實體而不是在Get請求上給予我們的實體。所以這個實體沒有變化跟蹤,處於Added狀態,並且如果我們將它作爲在Get階段交給我們的同一個實例處理,我們的數據庫就會大打折扣。

當前,您可以將EF4 STE標記爲已修改,應用更改並在實體真正新增或標記爲「添加」時進行保存。這就是你現在可以做的所有事情來支持這種情況。除非MVC團隊提出更好的模式來支持STE,或者除非在實例化模型以緩存實體實例時更改模型聯編程序的默認行爲......