我有两张表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
并从数据库中获取此对象的新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'的实例不能 被跟踪,因为具有相同密钥的此类型的另一个实例是 已被跟踪。添加新实体时,对于大多数关键类型a 如果没有设置密钥,则将创建唯一的临时密钥值(即,如果 key属性被赋予其类型的默认值)。如果你 明确设置新实体的关键值,确保不这样做 与现有实体或为其他实体生成的临时值发生冲突 新实体。附加现有实体时,请确保只有一个实体 具有给定键值的实体实例附加到上下文。
如何解决此问题?
答案 0 :(得分:5)
实体类型的实例&#39;客户&#39;无法跟踪,因为另一个 已经跟踪了具有相同密钥的此类型的实例
client
已创建_dbContext.Clients.Add(newClient);
个实例。
您需要在附加更新的条目之前分离第一个条目
之后
_dbContext.Clients.Add(newClient);
await _dbContext.SaveChangesAsync();
添加分离代码
_dbcontext.Entry(newClient).State = EntityState.Detached;
答案 1 :(得分:2)
您正在使用EF Core,就像编写原始SQL查询一样,这种方式优于ORM的许多优点。
您不需要ClientSecrets
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();
,因为EF Core可以找出关系本身。
Client
ClientSecret需要对ClientSecret
类的反向引用并不是问题,通过将您的秘密添加到模型中,您建立了Client
与Client
的关系。
现在保存时,EF Core会知道它首先要添加ClientSecret
然后添加{{1}} s
答案 2 :(得分:0)
您好,请添加以下内容对我有用: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();