我有一个继承自Document类的类,用于访问Resource类的属性。
public class UserProducts : Document
{
public string Id { get; set; }
public string DocumentType { get { return CardInboxDocumentTypes.UserProducts ; } private set { } }//just a enum to stored the document tyype
public string UserId { get; set; }//partition key
Public string Username { get; set; }
}
作为用户更新,它是用户名,我需要找到所有属于该用户的UserProducts并更新每个文档上的用户名。为此,我已经获取了像这样的文档
IEnumerable<UserProducts> UserProductslist = await GetItemsAsync<UserProducts >(x => x.UserId == "1234" && x.DocumentType == CardInboxDocumentTypes.UserProducts );
public async Task<IEnumerable<T>> GetItemsAsync<T>(Expression<Func<T, bool>> predicate) where T : class
{
IDocumentQuery<T> query = _client.CreateDocumentQuery<T>(documentCollectionUri:
UriFactory.CreateDocumentCollectionUri(databaseId: _databaseId, collectionId: _collectionId),
feedOptions: new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true })
.Where(predicate)
.AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
因为所有文档都属于同一个分区,所以我使用了该过程来更新所有文档。因此,要更新所有文档,我制作了一个动态列表并将其发送给过程。
List<dynamic> DoctoUpdate = new List<dynamic>();
foreach (UserProducts userProducts in UserProductslist )
{
userProducts.Username = "XYZ";
DoctoUpdate.Add(appusercarddoc);
}
StoredProcedureResponse<dynamic> storedProcedureResponseappuser = await ExecuteStoredProcedureAsync(procedureName: "sp_ReplaceDocument", partitionKey: "1234", documentList: DoctoUpdate);
public async Task<StoredProcedureResponse<dynamic>> ExecuteStoredProcedureAsync(string procedureName, string partitionKey, List<dynamic> documentList)
{
StoredProcedure storedProcedure = _client.CreateStoredProcedureQuery(_documentCollection.StoredProceduresLink)
.Where(sp => sp.Id == procedureName)
.AsEnumerable()
.FirstOrDefault();
return await _client.ExecuteStoredProcedureAsync<dynamic>(storedProcedureLink: storedProcedure.SelfLink, options: new RequestOptions { PartitionKey = new PartitionKey(partitionKey) }, procedureParams: documentList);
}
存储过程
function replaceDocument(docs) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var dbDocument
var count = 0;
if (!docs) throw new Error("The array is undefined or null.");
var docsLength = docs.length;
if (docsLength == 0) {
getContext().getResponse().setBody(0);
return;
}
tryReplaceDoc(docs[count], callback);
function tryReplaceDoc(doc, callback) {
var isAccepted = collection.replaceDocument(doc._self, doc, callback);
if (!isAccepted) getContext().getResponse().setBody(count);
}
function callback(err, doc, options) {
if (err) throw err;
count++;
if (count >= docsLength) {
getContext().getResponse().setBody(count);
} else {
tryReplaceDoc(docs[count], callback);
}
}
}
我不知道为什么值没有更新。据我所知,也许未获取doc._self属性。因此文档没有更新。 我使用的方法有什么问题,或者如何使用相同的分区键更新所有文档?
答案 0 :(得分:1)
当您从cosmos db中获得项目时,您确实通过将此类(在UserProducts
中指定为通用参数)而将从DB接收到的对象转换为自定义类ExecuteNextAsync
。由于您的类没有映射到cosmos doc _self
属性的属性-您在转换期间会丢失此数据。
并注意您的每次学习周期foreach (UserProducts userProducts in UserProductslist )
。您会在每次迭代时重新创建列表。