[英]How to update Entity Framework Core after adding a new table to the database
[英]How update entity after adding new entity in EF Core
我有两个表Client
和ClientSecret
。 这些表具有以下结构:
public class Client
{
public int Id { get; set; }
public string ClientId { get; set; }
public string ClientName { get; set; }
public List<ClientSecret> ClientSecrets { get; set; }
}
public class ClientSecret
{
public int Id { get; set; }
public string Description { get; set; }
public string Value { get; set; }
public DateTime? Expiration { get; set; }
public Client Client { get; set; }
}
我需要创建一个新的Client
设置ClientId
和ClientName
并从 DB 取回此对象的新Id
。
我试过这个( _dbContext
是通过构造函数中的 DI 系统获取的):
var newClient = new Client();
newClient.ClientName = client.ClientName;
newClient.ClientId = client.ClientId;
_dbContext.Clients.Add(newClient);
await _dbContext.SaveChangesAsync();
var newClientId = newClient.Id;
var clientToUpdate = await _dbContext.Clients.Where(x => x.Id == newClientId).SingleOrDefaultAsync();
clientToUpdate.ClientSecrets.AddRange(secrets);
_dbContext.Clients.Update(clientToUpdate);
await _dbContext.SaveChangesAsync();
我需要首先创建一个Client
因为表ClientSecrets
需要一个ClientId
来在该表中创建新记录。
我收到此错误消息:
在行中失败: _dbContext.Clients.Update(clientToUpdate);
InvalidOperationException:无法跟踪实体类型“Client”的实例,因为已在跟踪具有相同键的此类型的另一个实例。 添加新实体时,对于大多数键类型,如果未设置键(即,如果键属性为其类型分配了默认值),将创建一个唯一的临时键值。 如果您为新实体显式设置键值,请确保它们不会与现有实体或为其他新实体生成的临时值发生冲突。 附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文。
我该如何解决这个问题?
无法跟踪实体类型“Client”的实例,因为已在跟踪具有相同键的此类型的另一个实例
_dbContext.Clients.Add(newClient);
上已经创建了一个client
实例_dbContext.Clients.Add(newClient);
.
在附加更新的条目之前,您需要分离第一个条目
之后
_dbContext.Clients.Add(newClient);
await _dbContext.SaveChangesAsync();
添加用于分离的代码
_dbcontext.Entry(newClient).State = EntityState.Detached;
您正在使用 EF Core,就像您编写原始 SQL 查询时一样,这与 ORM 的许多优势相比更胜一筹。
您不需要ClientSecrets
的ClientId
,因为 EF Core 可以自己找出关系。
var newClient = new Client
{
ClientName = client.ClientName,
ClientId = client.ClientId,
ClientSecrets = secrets.ToList() // or ToArray or whatever it is
};
_dbContext.Clients.Add(newClient);
await _dbContext.SaveChangesAsync();
ClientSecret 需要对Client
类的反向引用不是问题,通过将您的秘密添加到模型中,您可以建立ClientSecret
到Client
的关系。
现在保存时,EF Core 会知道它必须先添加Client
,然后添加ClientSecret
嗨,请添加以下内容,它适用于 2020 年 9 月 25 日星期五。AsNoTracking 为我解决了这个问题。 因为我能够更新我的。 谢谢
var clientToUpdate = await _dbContext.AsNoTracking().Clients.Where(x => x.Id == newClientId).SingleOrDefaultAsync();
clientToUpdate.ClientSecrets.AddRange(secrets);
_dbContext.Clients.Update(clientToUpdate);
await _dbContext.SaveChangesAsync();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.