Efcore: Guid partition key for Entity Framework Core Cosmos DB provider

Created on 27 Feb 2020  路  7Comments  路  Source: dotnet/efcore

I'm trying to use the EF Core Cosmos DB provider and in my entity class I'm using a Guid as Id. Also, the Guid value will be the partition key in the Cosmos DB collection. The EF Core Cosmos DB provider documentation (https://docs.microsoft.com/en-us/ef/core/providers/cosmos/?tabs=dotnet-core-cli) says that the: "The partition key property can be of any type as long as it is converted to string." My entity class looks something like:
```C#
public class UserDto
{
[JsonProperty(PropertyName ="id")]
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public CountryDto Country { get; set; }

public override string ToString()
{
    return JsonConvert.SerializeObject(this);
}

}


In the DB context class I have something like:
```C#
public class CosmosDbContext : DbContext
{
    public CosmosDbContext(DbContextOptions<CosmosDbContext> options)  : base(options)
    {

    }

    public DbSet<UserDto> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserDto>()
            .ToContainer("Users");

        var converter = new GuidToStringConverter();
        modelBuilder.Entity<UserDto>()
            .Property("Id")
            .HasConversion(converter);

        modelBuilder.Entity<UserDto>()                
            .HasPartitionKey(x => x.Id);


        modelBuilder.Entity<UserDto>()
            .OwnsOne(u => u.Country);            
    }
}

Whenever I'm trying to add a new user to the collection I get the following error: Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: 400 Substatus: 1001 Reason: (Microsoft.Azure.Documents.DocumentClientException: Message: {"Errors":["PartitionKey extracted from document doesn't match the one specified in the header"]}

If I don't have a partitioning key in my collection and I remove code that sets the partitioning key and the value converter in the OnModelCreating method the code will work just fine.

According to this link: https://github.com/dotnet/efcore/issues/12086 the value converters should work. What am I missing?

Thank you!

closed-question customer-reported

Most helpful comment

@andreicroitoriu It's a scenario that EF Core won't support. If you get the same exception when the partition key is different from id then update the repro and we'll investigate.

All 7 comments

You shouldn't use id as the partition key because it will result in having only a single item in each partition, see https://github.com/dotnet/efcore/issues/18428

If you don't have a partition key just don't call HasPartitionKey

@AndriySvyryd I understand the result of using Id as partition key, but that is a separate discussion. If I use the Cosmos Db SDK to connect and work with the collection everything works fine, so I guess it must be an issue with the EF Core provider - unless I'm doing something wrong when I'm trying to configure the EF context...

@andreicroitoriu It's a scenario that EF Core won't support. If you get the same exception when the partition key is different from id then update the repro and we'll investigate.

@AndriySvyryd tested it with a different partition key and indeed it worked. Thank you for clearing that out. However, one last question if I may: what is the reason why EF Core won't support that? While I agree setting the partition key using the ID field is not ideal, Cosmos DB allows it...

We strive to help our users avoid pits of failure. For same reason for relation databases we don't allow foreign keys that target the same columns on which they are declared, even though it's supported by many databases.

@AndriySvyryd why is it a pit of failure? https://stackoverflow.com/a/54637561/442773 and from https://docs.microsoft.com/en-us/azure/cosmos-db/partitioning-overview#using-item-id-as-the-partition-key
" the item ID is naturally a great choice for the partition key."

@drdamour I didn't check the updates to Cosmos DB when I wrote the comment above. This was an issue in the early versions of the service. It does work fine now and is supported in EF Core 5.0

Was this page helpful?
0 / 5 - 0 ratings