« Mongodb and csharp » : différence entre les versions
Apparence
(27 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Category:.NET]] | [[Category:.NET]] | ||
= Links = | |||
* [https://www.mongodb.com/developer/languages/csharp/using-linq-query-mongodb-dotnet-core-application Using LINQ to Query MongoDB in a .NET Core Application] | |||
* [https://www.mongodb.com/developer/languages/csharp/create-restful-api-dotnet-core-mongodb Create a RESTful API with .NET Core and MongoDB] | |||
* [https://www.mongodb.com/developer/languages/csharp/joining-collections-mongodb-dotnet-core-aggregation-pipeline Joining Collections in MongoDB with .NET Core and an Aggregation Pipeline] | |||
* [https://www.mongodb.com/developer/languages/csharp C# and MongoDB] | |||
* [https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mongo-app?view=aspnetcore-9.0&tabs=visual-studio Create a web API with ASP.NET Core and MongoDB] | |||
= Access to a collection = | = Access to a collection = | ||
<kode lang='cs'> | <kode lang='cs'> | ||
var mongoClient = new MongoClient("MONGODB_CONNECTION_STRING"); | var mongoClient = new MongoClient("MONGODB_CONNECTION_STRING"); | ||
var database = mongoClient.GetDatabase("DB_NAME"); | var database = mongoClient.GetDatabase("DB_NAME"); | ||
var collection = database.GetCollection< | var collection = database.GetCollection<MyClass>("COLLECTION_NAME"); | ||
</kode> | </kode> | ||
= Filter = | = Dependency injection = | ||
<filebox fn='Program.cs'> | |||
builder.Services | |||
.Configure<MongoConfiguration>(builder.Configuration.GetSection("Mongo")) | |||
.AddSingleton<IMongoClient>(x => | |||
{ | |||
var mongoConfiguration = x.GetRequiredService<IOptions<MongoConfiguration>>().Value; | |||
var settings = MongoClientSettings.FromConnectionString(mongoConfiguration.ConnectionString); | |||
settings.LinqProvider = LinqProvider.V3; | |||
return new MongoClient(settings); | |||
}) | |||
.AddSingleton(x => | |||
{ | |||
var client = x.GetRequiredService<IMongoClient>(); | |||
var configuration = x.GetRequiredService<IOptions<MongoConfiguration>>().Value; | |||
return client.GetDatabase(configuration.DatabaseName); | |||
}) | |||
.AddSingleton(x => | |||
{ | |||
var database = x.GetRequiredService<IMongoDatabase>(); | |||
return database.GetCollection<MyCollection>(GetConfigurationValue("MyCollectionName")); | |||
}); | |||
</filebox> | |||
<filebox fn='MongoConfiguration.cs' collapsed> | |||
public class MongoConfiguration | |||
{ | |||
public string ConnectionString { get; set; } = string.Empty; | |||
public string DatabaseName { get; set; } = string.Empty; | |||
} | |||
</filebox> | |||
= Find = | |||
== Filter == | |||
<kode lang='cs'> | <kode lang='cs'> | ||
var builder = Builders<MyClass>.Filter; | var builder = Builders<MyClass>.Filter; | ||
FilterDefinition<MyClass> filter = builder.Empty; | |||
filter &= builder.Exists(x => x.Property1); | |||
filter &= builder.Eq(x => x.Property1, "value"); | |||
filter &= builder.In(x => x.Property1, new[] { "value1", "value2" }); // filter by Property1 equals to one of the values | |||
filter &= builder.AnyIn(x => x.Tags, new[] { "value1", "value2" }); // filter by string[] Tags property which contains at least value1 or value2 | |||
filter &= builder.All(x => x.Tags, new[] { "value1", "value2" }); // filter by string[] Tags property which contains at least value1 and value2, order doesn't matter | |||
var result = await collection | |||
.Find(filter) | |||
.SortByDescending(x => x.Property1) | |||
.Skip(100) | |||
.Limit(10) | |||
.ToListAsync(); | |||
var result = (await collection.FindAsync(filter)).ToList(); | |||
</kode> | |||
== Handle different types == | |||
<kode lang='cs'> | |||
// get all the documents | |||
var bsonDocumentCollection = database.GetCollection<BsonDocument>("MyCollection"); | |||
var filter = Builders<BsonDocument>.Filter.Empty; | |||
var result = await bsonDocumentCollection.Find(filter).ToListAsync(); | |||
// get all the Class1 document | |||
var class1Collection = database.GetCollection<Class1>("MyCollection"); | |||
await type1Collection.InsertOneAsync(new Class1 { Name = "Name1" }); | |||
var filter = Builders<Class1>.Filter.Eq(x => x.Type, nameof(Class1)); | |||
var filter = Builders<SimpleClass>.Filter.Exists(x => x.Name); // get all the documents which have a property Name | |||
var result = await class1Collection.Find(filter).ToListAsync(); | |||
class Class1 | |||
{ | |||
public ObjectId Id { get; set; } | |||
public string Name { get; set; } = string.Empty; | |||
public string Type { get; set; } = nameof(Class1); | |||
} | |||
</kode> | |||
= Pipeline = | |||
<kode lang='cs'> | |||
var stages = new BsonDocument[] | |||
{ | |||
MatchStage(getTimeSeriesQuery), | |||
ProjectionStage(), | |||
SortStage() | |||
}; | |||
var pipeline = PipelineDefinition<InputClass, OutputClass>.Create(stages); | |||
var results = (await myCollection.AggregateAsync(pipeline)).List(); | |||
BsonDocument MatchStage(GetTimeSeriesQuery getTimeSeriesQuery) | |||
{ | |||
var match = new BsonDocument("property1", "value1"); | |||
if (!string.IsNullOrEmpty(variable2)) | |||
{ | |||
match.AddRange( | |||
new BsonDocument("property2", variable2) | |||
); | |||
} | |||
return new BsonDocument("$match", match); | |||
} | |||
BsonDocument ProjectionStage() => | |||
new BsonDocument( | |||
"$project", | |||
new BsonDocument | |||
{ | |||
{ "_id", 0 }, | |||
{ "property1", 1 }, | |||
{ "property2", 1 } | |||
} | |||
); | |||
BsonDocument SortStage() => | |||
new BsonDocument("$sort", new BsonDocument("timestamp", 1)); | |||
</kode> | |||
= Insert / Update = | |||
<kode lang='cs'> | |||
// insert | |||
await itemMongoCollection.InsertOneAsync(item); | |||
FilterDefinition<Item> filter = Builders<Item>.Filter.Eq(nameod(Item.Id), item.Id); | |||
// update | |||
Item updatedItem = await itemMongoCollection.FindOneAndReplaceAsync(filter, item); | |||
// upsert | |||
var options = new FindOneAndReplaceOptions<Item, T> { IsUpsert = true }; | |||
await itemMongoCollection.FindOneAndReplaceAsync(filter, item, options); | |||
// patch | |||
UpdateDefinitionBuilder<Item> updateBuilder = Builders<Item>.Update; | |||
UpdateDefinition<Item> updateDefinition = Builders<Item>.Update.Combine( | |||
updateBuilder.Set(nameof(Item.Name), "updatedName"), | |||
updateBuilder.Set(nameof(Item.Available), false)); | |||
UpdateResult result = await itemMongoCollection.UpdateOneAsync(filter, updateDefinition); | |||
var success = result.ModifiedCount > 0; | |||
</kode> | |||
= [https://stackoverflow.com/questions/30333925/how-do-i-log-my-queries-in-mongodb-c-sharp-driver-2-0 Log] = | |||
<kode lang='cs'> | |||
var mongoUrl = new MongoUrl("MONGODB_CONNECTION_STRING"); | |||
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl); | |||
mongoClientSettings.ClusterConfigurator = cb => | |||
{ | |||
cb.Subscribe<CommandStartedEvent>(e => | |||
{ | |||
logger.LogTrace($"{e.CommandName} - {e.Command.ToJson()}"); | |||
}); | |||
}; | |||
this.mongoClient = new MongoClient(mongoClientSettings); | |||
</kode> | |||
Configure the [[Asp.net_core_7#Log|Log]] so it will be displayed in Visual Studio Output Debug window. | |||
* [https://www.mongodb.com/docs/drivers/csharp/current/fundamentals/logging/#configure-logging Configure logging] | |||
= Serialize a dictionary with an Enum as key = | |||
Error: An error occurred while serializing the Values property of class ...: When using DictionaryRepresentation.Document key values must serialize as strings | |||
<kode lang='cs'> | |||
class MyClass | |||
{ | |||
public ObjectId Id { get; set; } | |||
public Dictionary<MyEnum, int> Values { get; set; } = []; | |||
} | |||
// serialize the enum as string | |||
BsonSerializer.RegisterSerializer(new EnumSerializer<MyEnum>(BsonType.String)); | |||
</kode> | |||
= BsonDocument = | |||
<kode lang='cs'> | |||
var bsonDocument = BsonDocument.Parse(jsonDocument.RootElement.GetRawText()); | |||
var bsonDocument = myObject.ToBsonDocument(); | |||
bsonDocument["fieldName"] = "value"; | |||
</kode> | </kode> |
Version du 2 avril 2025 à 12:21
Links
- Using LINQ to Query MongoDB in a .NET Core Application
- Create a RESTful API with .NET Core and MongoDB
- Joining Collections in MongoDB with .NET Core and an Aggregation Pipeline
- C# and MongoDB
- Create a web API with ASP.NET Core and MongoDB
Access to a collection
var mongoClient = new MongoClient("MONGODB_CONNECTION_STRING");
var database = mongoClient.GetDatabase("DB_NAME");
var collection = database.GetCollection<MyClass>("COLLECTION_NAME");
|
Dependency injection
Program.cs |
builder.Services
.Configure<MongoConfiguration>(builder.Configuration.GetSection("Mongo"))
.AddSingleton<IMongoClient>(x =>
{
var mongoConfiguration = x.GetRequiredService<IOptions<MongoConfiguration>>().Value;
var settings = MongoClientSettings.FromConnectionString(mongoConfiguration.ConnectionString);
settings.LinqProvider = LinqProvider.V3;
return new MongoClient(settings);
})
.AddSingleton(x =>
{
var client = x.GetRequiredService<IMongoClient>();
var configuration = x.GetRequiredService<IOptions<MongoConfiguration>>().Value;
return client.GetDatabase(configuration.DatabaseName);
})
.AddSingleton(x =>
{
var database = x.GetRequiredService<IMongoDatabase>();
return database.GetCollection<MyCollection>(GetConfigurationValue("MyCollectionName"));
});
|
MongoConfiguration.cs |
public class MongoConfiguration
{
public string ConnectionString { get; set; } = string.Empty;
public string DatabaseName { get; set; } = string.Empty;
}
|
Find
Filter
var builder = Builders<MyClass>.Filter;
FilterDefinition<MyClass> filter = builder.Empty;
filter &= builder.Exists(x => x.Property1);
filter &= builder.Eq(x => x.Property1, "value");
filter &= builder.In(x => x.Property1, new[] { "value1", "value2" }); // filter by Property1 equals to one of the values
filter &= builder.AnyIn(x => x.Tags, new[] { "value1", "value2" }); // filter by string[] Tags property which contains at least value1 or value2
filter &= builder.All(x => x.Tags, new[] { "value1", "value2" }); // filter by string[] Tags property which contains at least value1 and value2, order doesn't matter
var result = await collection
.Find(filter)
.SortByDescending(x => x.Property1)
.Skip(100)
.Limit(10)
.ToListAsync();
var result = (await collection.FindAsync(filter)).ToList();
|
Handle different types
// get all the documents
var bsonDocumentCollection = database.GetCollection<BsonDocument>("MyCollection");
var filter = Builders<BsonDocument>.Filter.Empty;
var result = await bsonDocumentCollection.Find(filter).ToListAsync();
// get all the Class1 document
var class1Collection = database.GetCollection<Class1>("MyCollection");
await type1Collection.InsertOneAsync(new Class1 { Name = "Name1" });
var filter = Builders<Class1>.Filter.Eq(x => x.Type, nameof(Class1));
var filter = Builders<SimpleClass>.Filter.Exists(x => x.Name); // get all the documents which have a property Name
var result = await class1Collection.Find(filter).ToListAsync();
class Class1
{
public ObjectId Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Type { get; set; } = nameof(Class1);
}
|
Pipeline
var stages = new BsonDocument[]
{
MatchStage(getTimeSeriesQuery),
ProjectionStage(),
SortStage()
};
var pipeline = PipelineDefinition<InputClass, OutputClass>.Create(stages);
var results = (await myCollection.AggregateAsync(pipeline)).List();
BsonDocument MatchStage(GetTimeSeriesQuery getTimeSeriesQuery)
{
var match = new BsonDocument("property1", "value1");
if (!string.IsNullOrEmpty(variable2))
{
match.AddRange(
new BsonDocument("property2", variable2)
);
}
return new BsonDocument("$match", match);
}
BsonDocument ProjectionStage() =>
new BsonDocument(
"$project",
new BsonDocument
{
{ "_id", 0 },
{ "property1", 1 },
{ "property2", 1 }
}
);
BsonDocument SortStage() =>
new BsonDocument("$sort", new BsonDocument("timestamp", 1));
|
Insert / Update
// insert
await itemMongoCollection.InsertOneAsync(item);
FilterDefinition<Item> filter = Builders<Item>.Filter.Eq(nameod(Item.Id), item.Id);
// update
Item updatedItem = await itemMongoCollection.FindOneAndReplaceAsync(filter, item);
// upsert
var options = new FindOneAndReplaceOptions<Item, T> { IsUpsert = true };
await itemMongoCollection.FindOneAndReplaceAsync(filter, item, options);
// patch
UpdateDefinitionBuilder<Item> updateBuilder = Builders<Item>.Update;
UpdateDefinition<Item> updateDefinition = Builders<Item>.Update.Combine(
updateBuilder.Set(nameof(Item.Name), "updatedName"),
updateBuilder.Set(nameof(Item.Available), false));
UpdateResult result = await itemMongoCollection.UpdateOneAsync(filter, updateDefinition);
var success = result.ModifiedCount > 0;
|
Log
var mongoUrl = new MongoUrl("MONGODB_CONNECTION_STRING");
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
mongoClientSettings.ClusterConfigurator = cb =>
{
cb.Subscribe<CommandStartedEvent>(e =>
{
logger.LogTrace($"{e.CommandName} - {e.Command.ToJson()}");
});
};
this.mongoClient = new MongoClient(mongoClientSettings);
|
Configure the Log so it will be displayed in Visual Studio Output Debug window.
Serialize a dictionary with an Enum as key
Error: An error occurred while serializing the Values property of class ...: When using DictionaryRepresentation.Document key values must serialize as strings
class MyClass
{
public ObjectId Id { get; set; }
public Dictionary<MyEnum, int> Values { get; set; } = [];
}
// serialize the enum as string
BsonSerializer.RegisterSerializer(new EnumSerializer<MyEnum>(BsonType.String));
|
BsonDocument
var bsonDocument = BsonDocument.Parse(jsonDocument.RootElement.GetRawText());
var bsonDocument = myObject.ToBsonDocument();
bsonDocument["fieldName"] = "value";
|