mongoDB:C#驱动程序V2如何更新嵌套集合中的项目

汤玛士

我有以下课程设计:

public class UserDayStore
{
    public Guid Id { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public DateTime EndOfSubscription { get; set; }
    public bool active { get; internal set; }
    public DateTime LastModified;

    public List<DbDayRecord>  Days { get; set; }
}

public class DbDayRecord
{
    public Guid StoreId { get; set; }
    public DateTime LastModified { get; set; }
    public DateTime DateOfDay { get; set; }

    public String Quote { get; set; }

}

添加UserDayStore可以正常工作,也可以向其中添加嵌套项目List<Days>当我尝试更新DayRecord时,正如我在Robomongo中看到的那样,更新已完成。但是,当我尝试在UserStore集合中此后搜索文档时,出现此异常:

System.FormatException

反序列化类QuoteMyDayServer.ServerLogic.UserDayStore的Days属性时发生错误:无法反序列化BsonType'Document'中的'List'。

bei MongoDB.Driver.Linq.MongoQueryProviderImpl 1.Execute(Expression expression) bei MongoDB.Driver.Linq.MongoQueryProviderImpl1.Execute [TResult](Expression expression)bei System.Linq.Queryable.First [TSource](IQueryable1 source) bei QuoteMyDayServer.ServerLogic.QuoteDatabase.<SetUserState>d__10.MoveNext() in C:\Entwicklung\Apps\QuoteMyDay\Server\QuoteMyDayServer\QuoteMyDayServer\ServerLogic\QuoteDatabase.cs:Zeile 147. --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) bei System.Runtime.CompilerServices.TaskAwaiter1.GetResult()位于NancyTests.MongoTests.d__8.MoveNext()在C:\ Development \ Apps \ QuoteMyDay \ Server \ QuoteMyDayServer \ NancyTests \ MongoTests.cs:第148行。-从先前位置的批次监视结束则在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Xunit.Sdk.TestInvoker_1处触发了异常。 ()在C:\ BuildAgent \ work \ cb37e9acf085d108 \ src \ xunit.execution \ SDK \ Frameworks \ Runners \ TestInvoker.cs:第227行。-从发生异常的先前位置开始的堆栈监视结束- -位于System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务),位于System.Runtime.CompilerServices.TaskAwaiter。在C中的Xunit.Sdk.ExecutionTimer.d__4.MoveNext()处的HandleNonSuccessAndDebuggerNotification(任务任务)在C:\ BuildAgent \ work \ cb37e9acf085d108 \ src \ xunit.execution \ Sdk \ Frameworks \ ExecutionTimer.cs:第48行。---批处理从发生异常的先前位置进行监视-在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Xunit.Sdk.ExceptionAg。MoveNext( )在C:\ BuildAgent \ work \ cb37e9acf085d108 \ src \ xunit.core \ SDK \ ExceptionAggregator.cs:第90行。引发异常的位置-在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Xunit.Sdove.Exception(Aggregator.dext__9)C: \ BuildAgent \ work \ cb37e9acf085d108 \ src \ xunit.core \ SDK \ ExceptionAggregator.cs:第90行。引发异常的位置-在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Xunit.Sdove.Exception(Aggregator.dext__9)C: \ BuildAgent \ work \ cb37e9acf085d108 \ src \ xunit.core \ SDK \ ExceptionAggregator.cs:第90行。

System.FormatException

无法反序列化BsonType“文档”中的“列表”。

bei MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase 2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) bei MongoDB.Bson.Serialization.Serializers.SerializerBase1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext上下文,BsonDeserializationArgs args) Serialization.BsonClassMapSerializer`1.DeserializeMemberValue(BsonDeserializationContext上下文,BsonMemberMap memberMap)

如果存在一个具有相同“ DateOfDay”的记录,则此方法将更新DayRecord,否则它将插入一个新记录。

    public async Task<bool> UpdateDayRecord(Guid storeID, DbDayRecord dayRecord)
    {
        var stores = GetUserStores();

        var builder = Builders<UserDayStore>.Filter;
        var filter = builder.Eq("Id", storeID);
        var result = await stores.FindAsync(filter);

        if (!await result.AnyAsync()) // Check is a Store with that Id exists
        {
            return false;
        }
        dayRecord.StoreId = storeID;

        filter =  builder.ElemMatch("Days", Builders<DbDayRecord>.Filter.Eq("DateOfDay", dayRecord.DateOfDay));
        result = await stores.FindAsync(filter);


        if (await result.AnyAsync())
        {

            var update = Builders<UserDayStore>.Update.Set("Days", dayRecord).CurrentDate("LastModified");

            var updateResult = await stores.UpdateOneAsync(filter, update);

            return (updateResult.ModifiedCount == 1);
        }
        else
        {

            filter = Builders<UserDayStore>.Filter.Eq("Id", storeID);
            var update = Builders<UserDayStore>.Update.AddToSet("Days", dayRecord).CurrentDate("LastModified");

            var updateResult = await stores.UpdateOneAsync(filter, update);

            return (updateResult.ModifiedCount == 1);
        }
    }

调用方法并更新现有的DayRecord之后,尝试访问UserDayStore时出现上述异常:

    public async Task<Guid> GetStoreId (string username)
    { 
        var stores = GetUserStores();

        var filter = Builders<UserDayStore>.Filter.Eq("UserName", username);

        var result = await stores.FindAsync(filter);

        return result.First().Id;
    }

它在FindAsync调用中失败。

这是更新后的JSON文档的样子

{
    "_id" : LUUID("e858f1cc-c81d-7244-b8a0-8beec3c8e10d"),
    "LastModified" : ISODate("2016-04-23T10:43:17.293Z"),
    "UserName" : "TestUser",
    "Password" : "4242",
    "EndOfSubscription" : ISODate("2016-06-22T22:00:00.000Z"),
    "active" : true,
    "Days" : {
        "StoreId" : LUUID("e858f1cc-c81d-7244-b8a0-8beec3c8e10d"),
        "LastModified" : ISODate("2016-04-24T00:00:00.000Z"),
        "DateOfDay" : ISODate("2016-04-23T00:00:00.000Z"),
        "Quote" : "Testquote1"
    }
}
汤玛士

经过一番尝试和错误后,我想我知道找到了正确的方法:

    filter =  builder.ElemMatch("Days", Builders<DbDayRecord>.Filter.Eq("DateOfDay", dayRecord.DateOfDay));
    result = await stores.FindAsync(filter);

    if (await result.AnyAsync())  // Record already exists, update it
    {

        var update = Builders<UserDayStore>.Update.Set("Days.$", dayRecord).CurrentDate("LastModified");

        var updateResult = await stores.UpdateOneAsync(filter, update);

        return (updateResult.ModifiedCount == 1);
    }
    else // Add new Record to array
    {

        filter = Builders<UserDayStore>.Filter.Eq("Id", storeID);
        var update = Builders<UserDayStore>.Update.AddToSet("Days", dayRecord).CurrentDate("LastModified");

        var updateResult = await stores.UpdateOneAsync(filter, update);

        return (updateResult.ModifiedCount == 1);
    }

重要的一点在这里:

    var update = Builders<UserDayStore>.Update.Set("Days.$", dayRecord).CurrentDate("LastModified");

添加.$make mongo来更新数组元素。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从驱动程序v1迁移C#驱动程序v2中的更新文档

在C#驱动程序中更新mongodb集合比在Shell中更新要慢得多

如何使用C#驱动程序检查MongoDB中是否存在集合?

MongoDB C#驱动程序-如何在.NET中的联接集合上强制投影?

使用c#驱动程序在MongoDB中使用此对象的另一个属性更新嵌套集合中的对象属性

如何使用C#驱动程序删除mongodb文档中的嵌套数组元素

如何在MongoDB 2.7中使用MongoDB C#驱动程序更新通用类型

使用MongoDB和C#新驱动程序版本(2.0)更新集合中的嵌入式文档

如何使用C#驱动程序更新MongoDB数组中的子文档

如何将此控制台mongodb查询转换为C#mongo驱动程序v2?

MongoDb C#驱动程序2.0将项目添加到嵌套数组

使用C#驱动程序在嵌套mongo集合中添加新对象

MongoDB C#驱动程序重命名集合

MongoDB C# 驱动程序:嵌套查找 - 如何“加入”嵌套关系?

Java MongoDB驱动程序:如何更新集合中的所有文档?

使用C#Mongodb驱动程序在嵌套列表中查找项目

如何使用mongodb C#驱动程序获取子文档的集合?

如何使用Mongodb C#驱动程序加入多个集合

如何在 C# Mongodb 强类型驱动程序中删除嵌套文档的数组内的元素

如何使用C#驱动程序更新MongoDB中数组子文档中包含的数组子文档中的字段?

c# MongoDB 驱动程序,从嵌套数组中检索对象

MongoDB 驱动程序 C#:嵌套对象中的等效“包含”?

使用 csharp mongodb 驱动程序,如何更新列表中的项目?

MongoDB C#官方驱动程序批量更新

mongodb C#驱动程序更新多个字段

使用C#驱动程序的MongoDB更新阵列

我们如何使用MongoDB Java驱动程序在MongoDB中追加/更新集合的子文档?

如何使用MongoDB C#驱动程序更新泛型类型

使用MongoDB C#驱动程序从父子层次结构中查找和更新节点