我得定義爲通過記錄對象的新實例更新TableServiceContext中的記錄?
[DataServiceKey("PartitionKey", "RowKey")]
public class TableRecord
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTime Timestamp { get; set; }
public string Data { get; set; }
}
蔚藍表記錄對象的記錄被用作接受業務邏輯級數據對象,並將其序列化到數據屬性的代碼保存到前庫基礎設施的一部分表存儲以及在返回到客戶端之前對其進行反序列化,因此業務邏輯不知道關於記錄的任何內容以及有關PartitionKey和RowKey的信息。
這裏的庫法
public TEntity RegisterSave<TEntity>(TEntity entity, bool createNew)
{
var storeRec = _strategy.GetStoreRecord(entity);
if (createNew)
_context.AddObject(storeRec.TableName, storeRec.Record);
else
{
try
{
_context.AttachTo(storeRec.TableName, storeRec.Record, "*");
}
catch (InvalidOperationException)
{
// AttachTo can throw an exception if the entity is already being tracked.
// Ignore
}
_context.UpdateObject(storeRec.Record);
}
return entity;
}
的_strategy
負責正確映射實體類型的表名以及正確使用密鑰創建TableRecord和序列化的實體到記錄。 storeRec.Record
屬性是TableRecord
類的實例。這種方法適用於創建新記錄和讀取記錄。
但是,當我嘗試用新數據更新現有記錄時,更新失敗,抱怨它無法更新未由上下文跟蹤的實體。儘管如果單步執行調試器中的代碼,事實證明實際上有兩個例外發生 - 首先在AttachTo
方法中,該方法報告跟蹤具有相同密鑰的實體,並且在此之後UpdateObject
抱怨它不是。
我哪裏錯了?
得到它
好,一點點的幫助ilspy我已經找到了問題的根源。 DataServiceContext爲加載到上下文的實體維護兩個字典。一個字典的鍵是實體本身,另一個字典的鍵是實體ID,它實質上是實體URL。在AttachTo方法中,上下文驗證這兩個字典並拋出InvalidOperationException
,如果在其中的任何一箇中都找到了條目。但UpdateObject方法僅驗證密鑰實體本身的字典,如果未找到則驗證失敗。
看來DataServiceContext假定修改只能對同一個實體完成,默認情況下不支持實體將被新實例作爲整體替換。但是邏輯使用默認比較器的標準字典類,所以在爲TableRecord實現IEquatable接口後,所有工作都完美無缺。
所以我的解決辦法是:
[DataServiceKey("PartitionKey", "RowKey")]
public class TableRecord: IEquatable<TableRecord>
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTime Timestamp { get; set; }
public string Data { get; set; }
public bool Equals(TableRecord other)
{
if (other == null)
return false;
return PartitionKey.Equals(other.PartitionKey) && RowKey.Equals(other.RowKey);
}
public override bool Equals(object obj)
{
return Equals(obj as TableRecord);
}
public override int GetHashCode()
{
return PartitionKey.GetHashCode()^RowKey.GetHashCode();
}
}
我只是利用了MergeOption.NotTracking,簡單得多 – knightpfhor 2012-03-07 20:19:05
在我的方法中,表中有一個有效負載字段數據,其中有最新版本的對象序列化。所以最後寫贏的行爲就是我正在尋找的。但看起來我錯過了NoTracking選項背後的想法 - 它最適合這種情況。 – achekh 2012-03-12 18:15:42