Jen*_*nan 6 c# entity-framework entity-framework-core asp.net-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; }
}
Run Code Online (Sandbox Code Playgroud)
我需要全部创建一个新Client集,ClientId并从数据库中ClientName获取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();
Run Code Online (Sandbox Code Playgroud)
我需要先创建一个,Client因为该表ClientSecrets需要一个表,ClientId用于在该表中创建新记录。
我收到此错误消息:
行中的失败: _dbContext.Clients.Update(clientToUpdate);
InvalidOperationException:无法跟踪实体类型“客户端”的实例,因为已经跟踪了具有相同键的该类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置任何键(即,如果为键属性分配了其类型的默认值),则将创建唯一的临时键值。如果您为新实体明确设置键值,请确保它们不与现有实体或为其他新实体生成的临时值冲突。附加现有实体时,请确保仅将一个具有给定键值的实体实例附加到上下文。
如何解决此问题?
您正在使用 EF Core,就像您编写原始 SQL 查询时一样,这与 ORM 的许多优势相比更胜一筹。
您不需要ClientIdfor ClientSecrets,因为 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();
Run Code Online (Sandbox Code Playgroud)
ClientSecret 需要对Client类进行反向引用,这不是问题,通过将您的秘密添加到模型中,您可以建立ClientSecretto的关系Client。
现在保存时,EF Core 将知道它必须先添加Client,然后添加ClientSecrets
小智 6
无法跟踪实体类型“客户端”的实例,因为已经跟踪了具有相同密钥的该类型的另一个实例
在上已经client创建了一个实例_dbContext.Clients.Add(newClient);。
您需要先分离第一个条目,然后再附加更新的条目
后
_dbContext.Clients.Add(newClient);
await _dbContext.SaveChangesAsync();
Run Code Online (Sandbox Code Playgroud)
添加用于分离的代码
_dbcontext.Entry(newClient).State = EntityState.Detached;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6662 次 |
| 最近记录: |