我寫一個簡單的事件策劃的Web應用程序(使用BreezeJS /實體框架) - 用戶創建一個比賽實體,並要求服務器產生一個或多個建議計劃(只有我一個這篇文章的目的) 。BreezeJS:爲什麼Before/AfterSaveEntitiesDelegate中的刪除操作不會傳播回客戶端?
當用戶點擊「生成計劃」時,比賽(包括生成計劃所需的大量細節)應提交給服務器,服務器應刪除任何現有計劃,生成一個新計劃,應該更新側面模型。
完美契合命名爲save,我想!
問題是最後一步:更新客戶端模型。服務器添加的計劃實體按預期在客戶端中顯示,但刪除被忽略。即客戶最終以新舊計劃結束!
這裏是我的名爲save:
[注:在這個問題的說明和代碼省略了很多不相關的細節(如20個屬性和實體類型),以確保問題的尺寸減小]
[HttpPost]
public SaveResult MyNamedSave(JObject saveBundle)
{
_contextProvider.BeforeSaveEntitiesDelegate = RecalculatePlan;
return _contextProvider.SaveChanges(saveBundle);
}
private Dictionary<Type, List<EntityInfo>> RecalculatePlan(Dictionary<Type, List<EntityInfo>> arg)
{
// See https://stackoverflow.com/questions/14517945/using-this-context-inside-beforesaveentity:
var readonlyContext = new PontifexContext();
foreach (var eventInfo in arg[typeof(Tournament)])
{
var tournament = (Tournament)eventInfo.Entity;
var deletePlan = readonlyContext.Plans.First(p => p.TournamentId == tournament.Id);
arg[typeof(Plan)].Add(_contextProvider.CreateEntityInfo(deletePlan, EntityState.Deleted););
var addPlan = new Plan {TournamentId = tournament.Id, };
arg[typeof(Plan)].Add(_contextProvider.CreateEntityInfo(addPlan, EntityState.Added););
}
}
我試圖使用named-saving做他們不打算做的事情(即刪除和添加實體)嗎?
PS:我試着做一個明確的加法並保存使用readonlyContext和_contextProvider.Context,但真的沒有工作。
編輯:
如果我試圖從DB明確刪除舊的計劃像下面,什麼都不會發生:
arg[typeof(Plan)].Add(_contextProvider.CreateEntityInfo(deletePlan, EntityState.Deleted););
// Add this:
context.PlanEntries.Remove(deletePlan);
context.SaveChanges();
我猜這是因爲_contextProvider.Context已經老計劃在緩存中,所以刪除它「背後」(即使用另一個上下文)並沒有什麼區別。
如果我然後嘗試使用_contextProvider.Context刪除它,我從框架中得到一個奇怪的重複輸入錯誤。
我在我的智慧'結束!
編輯2:
下面是在保存請求和響應中的數據,通過IE的顯影劑工具記入日誌。
請求第一:
{
"entities": [
{
"Id": 1,
"EventName": "Test Tournament",
"EventTime": "2015-03-21T20:00:00.000Z",
"entityAspect": {
"entityTypeName": "Tournament:#Pontifex.Model",
"defaultResourceName": "Tournaments",
"entityState": "Unchanged",
"originalValuesMap": { },
"autoGeneratedKey": {
"propertyName": "Id",
"autoGeneratedKeyType": "Identity"
}
}
}
],
"saveOptions": { }
}
然後,服務器刪除現有計劃條目(ID = 10),並增加了一個新的(ID = 11),這是我直接在DB使用SELECT驗證。那很好。
但迴應是:
[
{
"$id": "1",
"$type": "Pontifex.Model.Tournament, Pontifex.Server",
"Id": 1,
"EventName": "Test Tournament",
"EventTime": "2015-03-21T20:00:00.000",
"Plans": [
{
"$id": "17",
"$type": "Pontifex.Model.Plan, Pontifex.Server",
"Id": 11,
"TournamentId": 1,
"Tournament": { "$ref": "1" }
}
],
"BoardPlan": null
}
]
在此迴應,被刪除的實體永遠不會出現,所以客戶端可以理解它保留在模型中。
增加的計劃(Id 11)確實出現,並且集成在客戶端模型中。
但是:從sbelinis的回答來看,以Server added object showing as added in client after save changes,所添加的計劃看來可能是一個機緣巧合的事實:
在你的具體的例子,保存,因爲它發生在製作成新的實體與BeforeSaveEntity方法的實體有關,但不應該依賴它。
但sbelinis例如如何正確添加實體出現不完整的(例如,它指的是其他地方沒有使用的局部變量saveMapAdditions)
我接受我自己的答案。我不確定這是否是一種糟糕的形式 - 填充自己的背部 - 但它確實描述了我的問題的解決方案... –