Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The instance of entity type 'Data' cannot be tracked because another instance with the same key value for {'__id'} is already being tracked

Error:

System.InvalidOperationException: ‘The instance of entity type ‘Data’ 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.’

My DbContext class:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

public class MyDBContext : DbContext
    {
        public DbSet<Metadata> Metadata { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new MetadataConfiguration());
        }
    }

My Repository class:

public class MetadataRepository : GenericRepository<Metadata>, IMetadataRepository
    {
        private const string _className = nameof(MetadataRepository);
        private new readonly MyDBContext _context;
        private readonly ILogger _logger;

        public MetadataRepository(MyDBContext context, ILogger logger) : base(context)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _logger = logger;
        }

        public async Task<Metadata> GetMetadataAsync(string id)
        {
            string methodName = $"{_className}.{nameof(GetMetadataAsync)}";
            _logger.LogInformation($"{methodName} started with id = {id}");
            var query = await _context.Metadata.AsNoTracking().FirstOrDefaultAsync(x => x.Id.ToString() == id);
            _logger.LogInformation($"{methodName} exited with query = {JsonConvert.SerializeObject(query)}");
            return query;
        }
    }

My Interface:

public interface IMetadataRepository : IGenericRepository<Metadata>
    {
        Task<Metadata> GetMetadataAsync(string id);
    }

My Entity Configuration class:

public class MetadataConfiguration : IEntityTypeConfiguration<Metadata>
    {
        public void Configure(EntityTypeBuilder<Metadata> builder)
        {
            builder
                 .HasNoDiscriminator()
                 .ToContainer(nameof(MyDBContext.Metadata))
                 .HasPartitionKey(x => x.PartitionKey)
                 .HasKey(x => x.Id);
            builder.HasMany(x => x.Data);
            builder.Property(x => x.Id).ToJsonProperty("id");
        }
    }

My Metadata object class:

public class Metadata
    {
        [Key]
        [JsonProperty("id")]
        public Guid Id { get; set; }

        [JsonProperty("partitionKey")]
        public string PartitionKey { get; set; }

        [JsonProperty ("data")]
        public List<Data> Data { get; set; }
    }

    public class Data
    {
        public string? Key { get; set; }
        public string? Value { get; set; }
    }

I’m trying to seed data to my cosmosDB for the first iteration:

public class DbInitializer
    {
        public static void Initialize(MyDBContext context)
        {
            context.Database.EnsureCreated();
            if (context.Metadata.Count() == 0)
            {
                Metadata metadata = new Metadata()
                {
                    Id = Guid.NewGuid(),
                    PartitionKey = "UserResponse",
                    Data = new List<Data>
                    {
                        new Data
                        {
                            Key = "illness",
                            Value = "Illness"
                        },
                        new Data
                        {
                            Key = "familyemergency",
                            Value = "Family emergency"
                        },
                        new Data
                        {
                            Key = "other",
                            Value = "Other"
                        }
                    }
                };
                //context.Entry<Metadata>(metadata).State = EntityState.Detached;
                context.Metadata.AddRange(metadata);    // Error occurs here
                context.SaveChanges();
            }
        }
    }

I’m trying to seed the data to my CosmosDB’s Metadata container for the first run.
In the DbInitializer.cs class, I’m ensuring the DB is created, then I’m checking if DB has Count == 0 or not, if it’s 0 then I’m inserting the data. But I’m getting the above said error whenever I try to Add data to Metadata container.
context.Metadata.AddRange(metadata); <- Error occurs here

I’ve tried various solution from other posts like adding AsNoTracking() or making the state as Detached state. But it’s all futile.
I’m not sure where is this other instance getting created from which is pointing to the same id!!

>Solution :

The problem is your Data, not Metadata. I have not worked with CosmosDB but it seems since you have not defined the id property for Data some kind of shadow one is created (the __id). Try defining Id for Data and fill it in too:

Metadata metadata = new Metadata()
{
    Id = Guid.NewGuid(),
    PartitionKey = "UserResponse",
    Data = new List<Data>
    {
        new Data
        {
            Id = Guid.NewGuid(),
            Key = "illness",
            Value = "Illness"
        },
        // ...
    }
};

Or try (it seems more appropriate) change HasMany to OwnsMany:

builder.OwnsMany(x => x.Data);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading