Cosmos DB update fails Unable to cast Guid to string

asp.net-core azure-cosmosdb entity-framework-core

Question

Tried to update a Cosmos DB record in ASP.NET core 3.1. But the update fails with the following message: "Unable to cast object of type 'System.Func'2[Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry,System.Guid]' to type 'System.Func'2[Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry,System.String]'

The error occurs on the saveCangesAsync(); Simplified, the code looks like:

// The service
public async Task<Todo> UpdateAsync(Todo entity)
{
  var response = ctx.Todos.Update(entity);
  await ctx.SaveChangesAsync(); // Error here
  return response.Entity;
}

// The entity Todo
public class Todo
{
  public Guid id { get; set; }
  [Required(ErrorMessage = "Description is required")]
  public string description { get; set; }
  ...
}

// The context
public class TodoDbContext : DbContext
{
    public DbSet<Todo> Todos { get; set; }
    public TodoDbContext(DbContextOptions<TodoDbContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultContainer("Todos");
    }
}

// The controller
[HttpPut]
public async Task<IActionResult> Put(Todo todo)
{
    try
    {
        if (ModelState.IsValid)
        {
            Todo td = await service.GetAsync(todo.id.ToString());

            if (td != null)
            {
                td.description = todo.description;
                var response = await service.UpdateAsync(td);
                return Ok(response);
            }

            return BadRequest("Not found.");
        }
        else
        {
            return BadRequest(ModelState);
        }
    }
    catch (Exception ex)
    {
        return BadRequest(ex.Message);  // Exception here
    }
}

I can insert, read, but not update, so following code runs fine (with a Guid as well)

public async Task<Todo> CreateAsync(Todo entity)
{
    entity.id = Guid.NewGuid();
    var response = await ctx.Todos.AddAsync(entity);
    await ctx.SaveChangesAsync();
    return response.Entity;
}

Thanks for any help!

1
0
3/18/2020 3:05:53 PM

Accepted Answer

Don't use "id", that will collide with the automatically generated id. Use another property or use "Id" (with a capital I) in stead, to solve the problem.

0
3/18/2020 7:28:06 PM

Popular Answer

Is there any reason you're using Guid as your id type? In your Todo class you could write it like so:

public class Todo
{
    [JsonProperty("id")
    public string Id { get; set; }

    [JsonProperty("description")
    [Required(ErrorMessage = "Description is required")]
    public string description { get; set; }
}

I'm assuming that you're using v3 of the Cosmos DB SDK. You would then just use Guid.NewGuid().ToString() to set the id as a Guid (but as a string type).



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow