C
C#3mo ago
Luluh

✅ Problem connecting entities on efcore

I'm new with blazor and efcore and i'm in trouble to connect 2 relation Error: ---> Npgsql.PostgresException (0x80004005): 23505: Duplicate key value violates unique constraint "PK_Blocks" Method:
public async Task AddPaletteAsync(Database.Palette palette, ApplicationUser user)
{
await using var context = await dbContextFactory.CreateDbContextAsync();

palette.UserId = user.Id;
context.Palettes.Add(palette);
await context.SaveChangesAsync();
}
public async Task AddPaletteAsync(Database.Palette palette, ApplicationUser user)
{
await using var context = await dbContextFactory.CreateDbContextAsync();

palette.UserId = user.Id;
context.Palettes.Add(palette);
await context.SaveChangesAsync();
}
18 Replies
Jimmacle
Jimmacle3mo ago
the error is saying that youre trying to insert an entity with a primary key value that another entity in the table already has
Luluh
LuluhOP3mo ago
im trying to create a new palette on db and connect blocks from another table to the palette, but it looks the db is trying to create another blocks insteaded connect
public class DatabaseContext(DbContextOptions<DatabaseContext> options, IConfiguration config) : IdentityDbContext<ApplicationUser>(options)
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql(config["Database:ConnectionString"]);

public DbSet<Block> Blocks { get; set; }
public DbSet<Palette> Palettes { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Block>()
.HasIndex(b => b.MinecraftId)
.IsUnique();

modelBuilder.Entity<Palette>()
.HasMany(p => p.Blocks)
.WithMany(b => b.Palettes)
.UsingEntity(j => j.ToTable("PaletteBlocks"));

modelBuilder.Entity<Palette>()
.HasOne(p => p.PlaceholderBlock)
.WithMany()
.HasForeignKey(p => p.PlaceholderBlockId)
.OnDelete(DeleteBehavior.Restrict);

modelBuilder.Entity<ApplicationUser>()
.HasMany(u => u.Palettes)
.WithOne(p => p.User)
.HasForeignKey(p => p.UserId);

modelBuilder.Entity<IdentityUserLogin<string>>(entity =>
{
entity.HasKey(l => new { l.LoginProvider, l.ProviderKey });
});

modelBuilder.Entity<IdentityUserRole<string>>(entity =>
{
entity.HasKey(r => new { r.UserId, r.RoleId });
});

modelBuilder.Entity<IdentityUserToken<string>>(entity =>
{
entity.HasKey(t => new { t.UserId, t.LoginProvider, t.Name });
});
}
}
public class DatabaseContext(DbContextOptions<DatabaseContext> options, IConfiguration config) : IdentityDbContext<ApplicationUser>(options)
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql(config["Database:ConnectionString"]);

public DbSet<Block> Blocks { get; set; }
public DbSet<Palette> Palettes { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Block>()
.HasIndex(b => b.MinecraftId)
.IsUnique();

modelBuilder.Entity<Palette>()
.HasMany(p => p.Blocks)
.WithMany(b => b.Palettes)
.UsingEntity(j => j.ToTable("PaletteBlocks"));

modelBuilder.Entity<Palette>()
.HasOne(p => p.PlaceholderBlock)
.WithMany()
.HasForeignKey(p => p.PlaceholderBlockId)
.OnDelete(DeleteBehavior.Restrict);

modelBuilder.Entity<ApplicationUser>()
.HasMany(u => u.Palettes)
.WithOne(p => p.User)
.HasForeignKey(p => p.UserId);

modelBuilder.Entity<IdentityUserLogin<string>>(entity =>
{
entity.HasKey(l => new { l.LoginProvider, l.ProviderKey });
});

modelBuilder.Entity<IdentityUserRole<string>>(entity =>
{
entity.HasKey(r => new { r.UserId, r.RoleId });
});

modelBuilder.Entity<IdentityUserToken<string>>(entity =>
{
entity.HasKey(t => new { t.UserId, t.LoginProvider, t.Name });
});
}
}
My DB
public class Block
{
public Guid Id { get; set; } = Guid.CreateVersion7();
public string MinecraftId { get; set; }
public int MapId { get; set; }
public string? ImageUrl { get; set; }

public Dictionary<string, string> Properties { get; set; } = new();
public Dictionary<string, string> GeneratorProperties { get; set; } = new();

public List<Palette> Palettes { get; set; } = [];
}

public class Palette
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }

public Guid PlaceholderBlockId { get; set; }
public Block PlaceholderBlock { get; set; }

public List<Block> Blocks { get; set; } = [];

public string UserId { get; set; }
public ApplicationUser User { get; set; }
}

public class ApplicationUser : IdentityUser
{
public List<Palette> Palettes { get; set; } = [];
}
public class Block
{
public Guid Id { get; set; } = Guid.CreateVersion7();
public string MinecraftId { get; set; }
public int MapId { get; set; }
public string? ImageUrl { get; set; }

public Dictionary<string, string> Properties { get; set; } = new();
public Dictionary<string, string> GeneratorProperties { get; set; } = new();

public List<Palette> Palettes { get; set; } = [];
}

public class Palette
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }

public Guid PlaceholderBlockId { get; set; }
public Block PlaceholderBlock { get; set; }

public List<Block> Blocks { get; set; } = [];

public string UserId { get; set; }
public ApplicationUser User { get; set; }
}

public class ApplicationUser : IdentityUser
{
public List<Palette> Palettes { get; set; } = [];
}
palette and blocks is a many to many relation
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Luluh
LuluhOP3mo ago
still having issues, i think the problem is not related with keys
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Luluh
LuluhOP3mo ago
nope, this problem is occuring because im trying to insert the palette on another dbcontext that i get the blocks, so the blocks is no more tracked by the dbcontext and the efcore tries to create a new block insteaded connect with the palette
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Luluh
LuluhOP3mo ago
thats the error
No description
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Luluh
LuluhOP3mo ago
i alread fixed that .
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Jimmacle
Jimmacle3mo ago
tebe i don't think this is helping @Luluh yes, if you are moving entities between dbcontext instances it will cause problems with tracking and it will think existing entities are new ones if you want it to work like this you'll need to inform the change tracker that the entities are updated, not new
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Luluh
LuluhOP3mo ago
yees, i fixed this initializing the dbcontext on the page instead reinitialize in every method on the service i think the db was trying to create the blocks again because the blocks were not being tracked
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
Luluh
LuluhOP3mo ago
because im getting error when multiple instances are running and quering the db in same time
Unknown User
Unknown User3mo ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiX3mo ago
If you have no further questions, please use /close to mark the forum thread as answered
Want results from more Discord servers?
Add your server