Specify some types in the same container but not others, is this possible?
See original GitHub issueDescribe the bug Iāve recently finished running through the Pluralsight course on data modelling in cosmos db and I thought it might be a fun exercise to see if I could implement the final container/type construction using the repository tooling. But I am unsure if either Iām not doing it right or itās not possible.
To Reproduce I started off simple and worked through the meta data into the same container. For those which donāt have access to the course itās essentially
Tag:
{
"id" :"",
"name" : "",
"type": "tag"
}
Category:
{
"id" :"",
"name" : "",
"type": "category"
}
Container: āmetaā Partition Key: ā/typeā
(not pasted an image from the course slide as unsure about copyright etc).
Reproduction code:
using Microsoft.Azure.CosmosRepository;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
const string databaseName = "datamodelling";
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddCosmosRepository(options =>
{
// do not do this; demo only to make obvious
options.CosmosConnectionString = "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
options.DatabaseId = databaseName;
options.ContainerPerItemType = false;
options.ContainerBuilder.Configure<Category>(builder =>
{
builder.WithContainer("meta")
.WithPartitionKey("/type");
});
options.ContainerBuilder.Configure<Tag>(builder =>
{
builder.WithContainer("meta")
.WithPartitionKey("/type");
});
});
})
.Build();
var tagsRepository = host.Services.GetService<IRepository<Tag>>();
await tagsRepository.CreateAsync(new Tag() { Name = "production" });
await tagsRepository.CreateAsync(new Tag() { Name = "staging" });
await tagsRepository.CreateAsync(new Tag() { Name = "development" });
var categoryRepository = host.Services.GetService<IRepository<Category>>();
await categoryRepository.CreateAsync(new Category() { Name = "Laptops" });
await categoryRepository.CreateAsync(new Category() { Name = "Desktops" });
await categoryRepository.CreateAsync(new Category() { Name = "Workstations" });
var tags = await tagsRepository.GetAsync(t => true);
//[Container("meta")]
//[PartitionKeyPath("/type")]
public class Tag : Item
{
public string Name { get; set; }
protected override string GetPartitionKeyValue()
{
return base.Type;
}
}
//[Container("meta")]
//[PartitionKeyPath("/type")]
public class Category : Item
{
public string Name { get; set; }
protected override string GetPartitionKeyValue()
{
return base.Type;
}
}
As you can see from the above I have tried the attributes to define the container and partition keys. I have also tried the builder options to define container and partition key values. And also various combinations of them both, but no luck.
Expected behavior Both types go into the container named āmetaā
Actual behavior Both types go into the container named ācontainerā which is the default container name in the package.
Environment summary SDK Version: latest (2.11.0) .NET Version: 6.0.0 OS Version (e.g. Windows, Linux, MacOSX): Windows 10
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Hi, since you are using the container builder, you need to set the container per item type property to true, this gives you full control over where each type is stored. Hope this helps, we need to add this to the docs really.
Yes, I can see where youāre coming from, with that set to
false
it will put all itemās in the same container, using just the/id
as the partition key, turning this to true is like saying, āI am taking control nowā if that makes sense. You tell eachIItem
which container and what partition key to use.