使用Entity Framework和cosmos db更新实体

时间:2019-10-30 14:42:25

标签: c# entity-framework-core azure-cosmosdb

11:59

发生以下异常:

_dbContext.Update(entity)

查看我配置DbContext的方式:

System.InvalidOperationException: 'Unable to track an entity of type 'User' because alternate key property 'id' is null. If the alternate key is not used in a relationship, then consider using a unique index instead. Unique indexes may contain nulls, while alternate keys must not.'

在cosmos模拟器中运行以下sql命令,返回正确的实体:

modelBuilder.Entity<User>().HasKey(p => p.Id);

如何使用Entity Framework作为ORM和Cosmos作为数据库提供程序来更新现有实体?

2 个答案:

答案 0 :(得分:1)

我站在一边测试,但是一切都很好。

我的代码:

Item.cs

为了重现您的问题,我使用“ ID”代替“ id”

    public class Item
    {
        public Item(string key, string content) => (this.key, this.content) = (key, content);

        public string ID { get; set; } = Guid.NewGuid().ToString();

        public string key { get; set; }

        public string content { get; set; }
    }

CosmosDBContext .cs

    public class CosmosDBContext : DbContext
    {
        public CosmosDBContext(DbContextOptions<CosmosDBContext> options) : base(options)
        {

        }

        public DbSet<Item> Items { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Set partition key, set container
            modelBuilder.Entity<Item>().ToContainer("JackTest");
            modelBuilder.Entity<Item>().HasKey("ID");
            modelBuilder.Entity<Item>().HasPartitionKey("key");
        }
    }

创建一项:

    _cosmosDBContext.Items.Add(new Item("aaa", "abcdefg"));
    _cosmosDBContext.SaveChanges(true);

从数据浏览器中,我们可以看到该项目已创建:

enter image description here

我们可以看到系统将生成默认的“ id”。

更新项目

    var item = _cosmosDBContext.Items.Where(i => i.content.Equals("abcdefg")).FirstOrDefault();
    item.content = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss.fffZ") + item.content;
    _cosmosDBContext.Update(item);
    _cosmosDBContext.SaveChanges(true);

项目已更新:

enter image description here

答案 1 :(得分:1)

从文档中: “与不连贯的实体合作 每个项目都必须具有一个ID值,该ID值对于给定的分区键是唯一的。默认情况下,EF Core通过使用“ |”将区分符和主键值连接起来来生成该值。作为分隔符。仅当实体进入“已添加”状态时才生成键值。如果实体在.NET类型上没有id属性来存储值,则在附加实体时可能会出现问题。 要解决此限制,可以手动创建和设置id值,或者将实体标记为首先添加,然后将其更改为所需的状态:“

https://docs.microsoft.com/en-us/ef/core/providers/cosmos