UpdateOneAsync

时间:2019-04-09 16:57:36

标签: c# mongodb linq mongodb-.net-driver

使用此包装器调用UpdateOneAsync时:

    public async Task<UpdateResult> UpdateDocument<T>(
        string sCollectionName, 
        Expression<Func<T, bool>> filter, 
        UpdateDefinition<T> update,
        bool bUpsert,
        System.Threading.CancellationToken cancellationToken
        )
    {
        IMongoDatabase db = _mongoClient.GetDatabase(_optionsMonitor.CurrentValue.databasename);

        IMongoCollection<T> collection = db.GetCollection<T>(sCollectionName);

        return await collection.UpdateOneAsync<T>(filter, update, new UpdateOptions() { IsUpsert = bUpsert }, cancellationToken);
    }

像这样:

private async Task<Models.Errors> UpdateDbOnSyncServerToBoardUpdate(
        CancellationToken cancel,
        MongoDB.Bson.BsonDocument bsonDocConfigurationToUpdate,
        DateTime dtUpdated,
        string sId,
        int iObjectId,
        string sAppName,
        string sModelName
        )
    {
        MongoDB.Driver.UpdateResult updateResult = null;
        Models.Errors errors = null;

        try
        {
            updateResult = await _db.UpdateDocument<Models.Database.NodeBoardModel>(
                Constants.NodeBoardCollectionName,
                node => node.Id == sId && 
                node.RemoteBoard.apps.SingleOrDefault(
                    app => app.appname == sAppName).objects.
                    SingleOrDefault(model => model.name == sModelName).config_docs.
                    Any(config => config.config_id == iObjectId),
                MongoDB.Driver.Builders<Models.Database.NodeBoardModel>.Update.
                Set(
                    node => node.RemoteBoard.apps[-1].objects[-1].config_docs[-1].config_doc, bsonDocConfigurationToUpdate).
                Set(
                    node => node.RemoteBoard.apps[-1].objects[-1].config_docs[-1].config_dt, dtUpdated),
                false,
                cancel
                );

我收到NotSupportedException:

  

不支持表达式树:{document} {RemoteBoard} {apps} .SingleOrDefault(app =>(app.appname ==“ eACM”))。objects.SingleOrDefault(model =>(model.name == “标签”))。config_docs

我感觉我以错误的方式或MongoDb不支持的方式使用LINQ关键字,但是很难准确地指出问题所在。

我无法对堆栈进行任何跟踪:

  在MongoDB.Driver.Linq.Processors.EmbeddedPipeline.EmbeddedPipelineBinder.BindNonMethodCall(表达式节点)上的

     在MongoDB.Driver.Linq.Processors.PipelineBinderBase 1.BindPipeline(Expression node) at MongoDB.Driver.Linq.Processors.PipelineBinderBase 1.BindMethodCall(MethodCallExpression节点)处      在MongoDB.Driver.Linq.Processors.EmbeddedPipeline.EmbeddedPipelineBinder.Bind(表达式节点,IBindingContext父级)      在MongoDB.Driver.Linq.Processors.SerializationBinder.VisitMethodCall(MethodCallExpression节点)      在System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor访问者)      在MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(表达式节点)上      在System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression节点)      在MongoDB.Driver.Linq.Processors.SerializationBinder.VisitBinary(BinaryExpression节点)      在System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor访问者)      在MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(表达式节点)上      在MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate [TDocument](表达式1 predicate, IBsonSerializer 1 parameterSerializer,IBsonSerializerRegistry serializerRegistry)处      在MongoDB.Driver.MongoCollectionImpl 1.ConvertWriteModelToWriteRequest(WriteModel 1模型上,Int32索引)      在System.Linq.Enumerable.SelectIterator [TSource,TResult](IEnumerable 1 source, Func 3选择器)处+ MoveNext()      在System.Collections.Generic.List 1.AddEnumerable(IEnumerable 1上可枚举)      在System.Linq.Enumerable.ToList [TSource](IEnumerable 1 source) at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation..ctor(CollectionNamespace collectionNamespace, IEnumerable 1个请求,MessageEncoderSettings messageEncoderSettings)处      在MongoDB.Driver.MongoCollectionImpl 1.CreateBulkWriteOperation(IEnumerable 1个请求中,使用BulkWriteOptions选项)      在MongoDB.Driver.MongoCollectionImpl 1.BulkWriteAsync(IClientSessionHandle session, IEnumerable 1个请求中,BulkWriteOptions选项,CancellationToken cancelledToken)      在MongoDB.Driver.MongoCollectionImpl 1.UsingImplicitSessionAsync[TResult](Func 2 funcAsync,CancellationToken cancelledToken处)      在MongoDB.Driver.MongoCollectionBase 1.UpdateOneAsync(FilterDefinition 1过滤器上,UpdateDefinition 1 update, UpdateOptions options, Func 3 bulkWriteAsync)      在C:\ GIT \ app-manager \ APIMM \ ServerLevelConfiguration \ WebApplication \ Services \ ConcreteDatabase中的WebApplication.Services.ConcreteDatabase.UpdateDocument [T](字符串sCollectionName,表达式1 filter, UpdateDefinition 1更新,布尔bUpsert,CancellationToken cancelledToken)处。 CS:第131行      在Web应用程序.Services.SyncBoardDatabaseBackgroundService.UpdateDbOnSyncServerToBoardUpdate(CancellationToken取消,BsonDocument bsonDocConfigurationToUpdate,DateTime dtUpdated,字符串sId,Int32 iObjectId,字符串sAppName,字符串sModelName)中位于C:\ GIT \ app-manager \ APIMM \ ServerBackground \ Web。 cs:353行

模型类:

public class NodeBoardModel
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    [BsonElement]
    public NodeBoardRemoteModel RemoteBoard { get; set; }
}

public class NodeBoardRemoteModel
{
    [BsonElement]
    public List<NodeBoardAppModel> apps { get; set; }
}

public class NodeBoardAppModel
{
    [BsonElement]
    public string appname { get; set; }

    [BsonElement]
    public List<NodeBoardObjectModel> objects { get; set; }
}

public class NodeBoardObjectModel
{
    [BsonElement]
    public string name { get; set; }

    [BsonElement]
    public List<NodeBoardObjectConfigurationModel> config_docs { get; set; }
}

public class NodeBoardObjectConfigurationModel
{
    [BsonElement]
    public BsonDocument config_doc { get; set; }

    [BsonElement]
    public DateTime config_dt { get; set; }

    [BsonElement]
    public int config_id { get; set; }
}

1 个答案:

答案 0 :(得分:2)

当您尝试构建Update语句时,问题开始了。您可能知道,-1将作为索引传递给translated$ positional operator

  

位置$运算符不能用于遍历一个以上数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为$占位符的替换是单个值

此外,您尝试使用SingleOrDefault建立过滤条件,并且.NET MongoDB驱动程序无法将其转换为任何MongoDB查询语法运算符。

该如何解决?

您可以尝试使用documentation语法来代替使用位置运算符。

var filter = Builders<NodeBoardModel>.Filter.Eq(f => f.Id, sId);
var update = Builders<NodeBoardModel>.Update.Set("RemoteBoard.apps.$[app].objects.$[object].config_docs.$[configdoc].config_dt", dtUpdated);

var arrayFilters = new List<ArrayFilterDefinition>();
ArrayFilterDefinition<BsonDocument> appFilter = new BsonDocument("app.appname", new BsonDocument("$eq", sAppName));
ArrayFilterDefinition<BsonDocument> objectFilter = new BsonDocument("object.name", new BsonDocument("$eq", sModelName));
ArrayFilterDefinition<BsonDocument> configDocFilter = new BsonDocument("configdoc.config_id", new BsonDocument("$eq", iObjectId));

arrayFilters.AddRange(new[] { appFilter, objectFilter, configDocFilter });

var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };

var res = Col.UpdateOne(filter, update, updateOptions);