首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误:“备用键属性'id‘为空”,并“更新”调用Cosmos DB和实体框架核心3.1.2

错误:“备用键属性'id‘为空”,并“更新”调用Cosmos DB和实体框架核心3.1.2
EN

Stack Overflow用户
提问于 2020-03-15 02:59:52
回答 2查看 1.7K关注 0票数 6

假设我有一个简单的PersonModel模型,如下所示,我从ASP.NET Core3.1Bazor或MVC UI (web表单)更新了ASP.NET属性:

代码语言:javascript
复制
public class PersonModel 
{
  public Guid PersonModelId { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

我将模型发送到http触发的Azure函数并绑定到模型。这就是我实现EF Core的地方,并执行以下操作来更新它:

代码语言:javascript
复制
public async Task<int> UpdateAsync(TEntity entity)
{
  _dbSet.Attach(entity); //<--this throws the error
  _dbContext.Entry(entity).State = EntityState.Modified;
  return await _dbContext.SaveChangesAsync();
}

我没有问题用这个模型创建或删除实体,并且给定以下文章,我不认为从任何特定的存储库需求(例如分区键或主键等)创建一个“干净”的模型是什么问题。但是,如果没有得到以下错误,我似乎无法运行更新代码:

无法跟踪'PersonModel‘类型的实体,因为备用键属性'id’为null。

是否有人知道模型周围的特定需求,并使用此方法更新实体?有没有像docs文章中的示例那样简单/优雅的替代方案?

我尝试过_dbContext.Update(entity),但是我得到了完全相同的错误,这使我相信我的模型需要一个"ID“属性。

我还尝试修改我的DbContext设置,如下所示:

代码语言:javascript
复制
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<PersonModel>().HasAlternateKey(p => p.PersonModelId);
}

...but --这只会给出同样的错误,也不会改变实体的存储方式。

更新

根据下面被接受的答案的指导,我编写了以下修改来完成这项工作:

代码语言:javascript
复制
public async Task<int> UpdateAsync(TEntity entity)
{
  var entry = _dbSet.Add(entity);
  entry.State = EntityState.Unchanged;
  _dbContext.Update(entity);
  return await _dbContext.SaveChangesAsync();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-15 04:08:16

编辑:我相信这个问题是由EF Core为每个名为"id“的项目自动生成的属性引起的,特别是所有在模型中定义的键都是低限制的和独立的。似乎是特定于宇宙数据库提供程序,空值问题在EF核心->数据库提供程序-> Cosmos的文档中在“使用断开连接的实体”一节中注意到。

显然,EF Core只在实体进入“添加”状态时才生成此属性。因此,当您调用附加时,这个"id“属性为null,因此是异常。文档中列出了一个解决办法,并给出了比我更好的解释。

链接到下面的EF核心文档页为宇宙供应商。滚动到概述页面的底部,以找到涵盖此内容的“断开连接的实体”部分。

https://learn.microsoft.com/en-us/ef/core/providers/cosmos/?tabs=dotnet-core-cli#working-with-disconnected-entities

票数 4
EN

Stack Overflow用户

发布于 2020-06-04 10:17:06

根据这个问题1,您需要获取条目并显式地设置item id:

代码语言:javascript
复制
public async Task<T> UpdateItemAsync(string id, T item)
    {
        var itemEntry = context.Entry(item);            
        itemEntry.Property<string>("id").CurrentValue = "Item|" + id;
        itemEntry.State = EntityState.Modified;            
        await context.SaveChangesAsync();
        return itemEntry.Entity;

    }

1

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60689345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档