Reputation: 13
I am currently working on an MVC application using MongoDB and I'm generally a rookie with development. This my first foray into MongoDB; I have zero formal training with Mongo and now I'm stuck. My question is:
What is the correct syntax for updating data in a Mongo database using the latest C# driver and linq?
I'm trying to update a single user's information which is represented by this "PersonDTO" object:
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;
}
}
I have a predefined Mongo Context that I use in my service layer:
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");
}
}
}
And although I don't have an issue inserting data using the following method:
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;
}
I am having no luck finding the correct syntax to perform an update. I have only made it this far in the application watching (slightly outdated) tutorials and poring over stackoverflow answers. I know that much more experienced devs would be able to read through the driver documentation and figure this out on their own but I'm not knowledgeable enough to do that myself which is why I'm posting this question. My best guess so far has been this method:
public async void UpdateUserAsync(PersonDTO thisUser)
{
try
{
var User = ctx.People.FindOneAndUpdateAsync(x => x.MongoID == thisUser.MongoID, thisUser);
return;
}
catch
{
}
}
But VS is warning me that "The type arguments for method 'IMongoCollection.FindOneAndUpdateAsync(FilterDefinition, UpdateDefinition, FindOneAndUpdateOptions, CancellationToken)' cannot be inferred from usage." And suggesting that I "Try specifying the type arguments explicitly."
I have been sitting here basically guessing for the last 45 minutes on how to get this to compile and work but I can't figure it out. Does anyone know to write this correctly? And can you explain what arguments it's looking for? I really don't understand this driver very well and I need some help.
Upvotes: 1
Views: 2316
Reputation: 9679
In your case you are not doing any update you are doing replace, so you just replace all User properties with new. Usage is:
coll.ReplaceOne(x=>x.MongoID == thisUser.MongoID, thisUser);
If you don't want to replace complete Document, you could use update and update just certain properties, for example, set only firstname
:
coll.UpdateOne(x=>x.MongoID == thisUser.MongoID,
Builders<PersonDTO>.Update.Set(x=>x.firstName, thisUser.firstName));
I mentioned synchrone methods, it works the same with asynchrone too.
Upvotes: 1