跨分区获取数据时,_self属性未获取

时间:2018-06-20 15:03:09

标签: azure azure-cosmosdb

我有一个继承自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属性。因此文档没有更新。 我使用的方法有什么问题,或者如何使用相同的分区键更新所有文档?

1 个答案:

答案 0 :(得分:1)

当您从cosmos db中获得项目时,您确实通过将此类(在UserProducts中指定为通用参数)而将从DB接收到的对象转换为自定义类ExecuteNextAsync。由于您的类没有映射到cosmos doc _self属性的属性-您在转换期间会丢失此数据。

并注意您的每次学习周期foreach (UserProducts userProducts in UserProductslist )。您会在每次迭代时重新创建列表。