How update entity after adding new entity in EF Core

asp.net-core c# entity-framework entity-framework-core

Question

I have a two tables Client and ClientSecret. The tables have following structure:

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; }
}

I need for of all create a new Client set the ClientId and ClientName and get back a new Id of this object from DB.

I have tried this (_dbContext is getting via DI system in the constructor):

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();

I need first create a Client because the table ClientSecrets needs a ClientId for creating a new records into this table.

I got this error message:

Failed the in the row with: _dbContext.Clients.Update(clientToUpdate);

InvalidOperationException: The instance of entity type 'Client' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.

How can I fix this issue?

1
6
8/12/2017 7:22:40 PM

Accepted Answer

The instance of entity type 'Client' cannot be tracked because another instance of this type with the same key is already being tracked

there is already an instance of client created on _dbContext.Clients.Add(newClient);.

you need to Detach the first entry before attaching your updated entry

after

_dbContext.Clients.Add(newClient);
await _dbContext.SaveChangesAsync();

add code for detaching

_dbcontext.Entry(newClient).State = EntityState.Detached;
7
8/12/2017 7:45:02 PM

Popular Answer

You are using EF Core like when you write raw SQL queries, which kind of beats many of the advantages of an ORM.

You don't need the ClientId for ClientSecrets, because EF Core can figure out the relations itself.

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();

It's not a problem that ClientSecret requires a back reference to the Client class, by adding your secrets to the model, you establish a relationship of ClientSecret to Client.

When you save now, EF Core will know it has first to add the Client and then add the ClientSecrets



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow