-1

I want to add or update data in database from url (json), but this data already has the id value.

JSON file

[
    {
        "id": 0,
        "first_name": "Tony",
        "last_name": "Stark",
        "date": "2008-07-06"
    },
    {
        "id": 1,
        "first_name": "David",
        "last_name": "Guetta",
        "date": "2008-08-05"
    },
...

Model

public class Person
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string FirstName{ get; set; }
    [Required]
    public string LastName{ get; set; }
    [Required]
    public DateTime Date { get; set; }
}

Controller Index method:

public async Task<IActionResult> Index()
{
    string json;

    using (HttpClient client = new HttpClient())
    {
       json = client.GetStringAsync(Url).Result;
    }

    var people = JsonConvert.DeserializeObject<List<Person>>(json);

    if (people is not null)
    {
        await _context.AddRangeAsync(people);
        await _context.SaveChangesAsync();
    }

    return _context.People != null ?
                View(await _context.People.ToListAsync()) :
                Problem("Entity set 'ApplicationDbContext.People'  is null.");
}

After loading this page, the error shows up, problem with the key and id. I know that the problem is that json data has the id values, but I don't know how to avoid that. Is there any solution. How to keep id values from json and tell the database "please, don't generate the id values, take the id values from my converted json file"

InvalidOperationException: The instance of entity type 'Person' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

Thanks a lot

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I do not think that the id is your problem, unless it is not unique in the input data. Have a look here, https://stackoverflow.com/questions/48202403/instance-of-entity-type-cannot-be-tracked-because-another-instance-with-same-key, there are many ptoposed solutions. – justhere May 29 '22 at 14:15
  • " I want to add or update data" ??? to add needs different code then to update. You have to decide what do you want – Serge May 29 '22 at 16:06

1 Answers1

0

I have finally found the solution. It has been required another data annotation. So the Sql server will not increment the Id

[DatabaseGenerated(DatabaseGeneratedOption.None)]

Model

public class Person
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    [Required]
    public string? FirstName { get; set; }
    [Required]
    public string? LastName { get; set; }
    [Required]
    public DateTime Date { get; set; }
}

And then the method that actually do the add or update data, because if the table is already populated it truncate the table first.

public async Task<IActionResult> GetUpToDateData()
{
    string json;
    using (HttpClient client = new())
    {
        json = client.GetStringAsync(Url).Result;
    }

    var people = JsonConvert.DeserializeObject<List<Person>>(json);

    if (people is not null)
    {
        await _context.Database.ExecuteSqlRawAsync("TRUNCATE TABLE [People]");
        await _context.AddRangeAsync(people);
        await _context.SaveChangesAsync();
    }

    return RedirectToAction(nameof(Index));
}