在 MVC 应用程序中使用 C# Driver 2.3 在 MongoDB 3.4 中插入和更新数据

Inserting & Updating Data in MonogoDB 3.4 with C# Driver 2.3 in an MVC application

我目前正在使用 MongoDB 开发 MVC 应用程序,我通常是开发方面的新手。这是我第一次涉足 MongoDB;我对 Mongo 的正式培训为零,现在我被困住了。我的问题是:

使用最新的 C# 驱动程序和 linq 在 Mongo 数据库中更新数据的正确语法是什么?

我正在尝试更新此 "PersonDTO" 对象表示的单个用户的信息:

public class PersonDTO
{

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

    [Display(Name = "Last Name")]
    public string lastName { get; set; }

    [Display(Name = "First Name")]
    public string firstName { get; set; }

    [Display(Name = "Alias")]
    public string alias { get; set; }

    public PersonContactInfo contactInfo { get; set; }

    [BsonDateTimeOptions(Kind = DateTimeKind.Local, DateOnly = true)]
    [Display(Name = "Member Since")]
    public DateTime? dateJoined { get; set; }

    [BsonIgnoreIfNull]
    [BsonElement("subjectIds")]
    public List<string> AdminSubjectIds = new List<string>();

    [BsonIgnoreIfNull]
    [BsonElement("topicIds")]
    public List<string> ModeratorTopicIDs = new List<string>();

    public PersonDTO()
    {
        MongoID = string.Empty;
        lastName = string.Empty;
        firstName = string.Empty;
        alias = string.Empty;
        dateJoined = null;
    }
}

public class PersonContactInfo
{
    [Display(Name = "Email")]
    public string email { get; set; }

    [BsonIgnoreIfNull]
    [Display(Name = "Phone Number")]
    public string phoneNumber { get; set; }

    public PersonContactInfo()
    {
        email = string.Empty;
        phoneNumber = string.Empty;
    }

}

我有一个预定义的 Mongo 我在我的服务层中使用的上下文:

public class MongoClientContext
{
    public IMongoDatabase Db;
    public MongoClientContext()
    {
        var client = new MongoClient(Settings.Default.xxxConnectionString);
        Db = client.GetDatabase(Settings.Default.xxxDatabaseName);
    }

    public IMongoCollection<PersonDTO> People
    {
        get
        {
            return Db.GetCollection<PersonDTO>("person");
        }
    }

}

虽然我在使用以下方法插入数据时没有问题:

    public async Task<PersonDTO> InsertUserAsync(PersonDTO newUser)
    {
        try
        {
            newUser.MongoID = ObjectId.GenerateNewId().ToString();
            DateTime today = DateTime.Now;
            newUser.dateJoined = today.Date;
            await ctx.People.InsertOneAsync(newUser);
        }

        catch (Exception ex)
        {
            string failMsg = "Failed to insert " + newUser.firstName + " " + newUser.lastName + ". Exception message: " + ex;
            newUser.MongoID = failMsg;
        }

        return newUser;
    }

我找不到正确的语法来执行更新。我只是在观看(稍微过时的)教程和仔细研究 Whosebug 答案的应用程序中做到了这一点。我知道更有经验的开发人员将能够通读驱动程序文档并自行解决这个问题,但我自己的知识不足以做到这一点,这就是我发布这个问题的原因。到目前为止我最好的猜测是这个方法:

    public async void UpdateUserAsync(PersonDTO thisUser)
    {
        try
        {
            var User = ctx.People.FindOneAndUpdateAsync(x => x.MongoID == thisUser.MongoID, thisUser);
            return;
        }

        catch
        {

        }
    }

但是 VS 警告我 "The type arguments for method 'IMongoCollection.FindOneAndUpdateAsync(FilterDefinition, UpdateDefinition, FindOneAndUpdateOptions, CancellationToken)' cannot be inferred from usage." 并建议我 "Try specifying the type arguments explicitly."

在过去的 45 分钟里,我一直坐在这里,基本上是在猜测如何让它编译和工作,但我想不出来。有谁知道正确地写这个?你能解释一下它在寻找什么论点吗?我真的不太了解这个驱动程序,我需要一些帮助。

在你的情况下,你没有做任何更新你正在做替换,所以你只需用新的替换所有用户属性。用法是:

coll.ReplaceOne(x=>x.MongoID == thisUser.MongoID, thisUser);

如果您不想替换完整的文档,您可以使用更新并仅更新某些属性,例如仅设置 firstname:

coll.UpdateOne(x=>x.MongoID == thisUser.MongoID, 
           Builders<PersonDTO>.Update.Set(x=>x.firstName, thisUser.firstName));

我提到了同步方法,它与异步方法也一样。