Reputation: 9501
I use EntityFramework SQLite and got stuck with weird bug. I searched for the similar problems, but no solution suits my case.
In my real project it does not work at all. (with the same exception) In the example I made when I execute code first time it works fine (when db is just created), when I run it again I got exception:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 'Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.'
Minimum reproducible sample can be found here.
The code is rather trivial:
using (var ctx = new SqliteDbContext("data.db"))
{
ctx.Database.Migrate();
ctx.UserReferencesData.Add(new UserReferencesData()
{
ColumnId = Guid.NewGuid(),
MetadataId = -2,
RowId = 1,
ColumnType = 1,
StringValue = "asdf",
});
ctx.SaveChanges();
}
Model is also rather simple, but I suspect that it has to do with particular column or index, since other tables works fine:
[Table("UserReferencesData")]
[Index(nameof(RowId))]
public class UserReferencesData
{
[Key]
public int Id
{
get;
set;
}
public int MetadataId
{
get;
set;
}
public int RowId
{
get;
set;
}
public Guid ColumnId
{
get;
set;
}
public int ColumnType
{
get;
set;
}
//type 0
public DateTime? DateValue
{
get;
set;
}
//type 1
public string StringValue
{
get;
set;
}
//type 2
public int? IntValue
{
get;
set;
}
//type 3
public double? DoubleValue
{
get;
set;
}
//type 4
public bool? BoolValue
{
get;
set;
}
//type 5
public decimal? DecimalValue
{
get;
set;
}
}
dbcontext:
public class SqliteDbContext : DbContext
{
private string _dbPath = @"data.db";
public SqliteDbContext(string dbPath)
{
_dbPath = dbPath;
}
//ctor for migration
public SqliteDbContext(DbContextOptions<SqliteDbContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var path = $"Data Source=\"{_dbPath}\"";
optionsBuilder.UseSqlite(path);//
#if DEBUG
optionsBuilder.EnableSensitiveDataLogging(true);
optionsBuilder.LogTo(s=>System.Diagnostics.Debug.WriteLine(s));
#endif
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserReferencesData>()
.HasOne<UserReferencesMetadata>()
.WithMany()
.HasForeignKey(d => d.MetadataId);
}
public virtual DbSet<UserReferencesData> UserReferencesData
{
get;
set;
}
public virtual DbSet<UserReferencesMetadata> UserReferencesMetadata
{
get;
set;
}
}
When I execute insert query in SQLite db browser row is added. But second one returns 0 rows (I logged queries which are used by Entity Framework):
INSERT INTO "UserReferencesData" ("BoolValue", "ColumnId", "ColumnType", "DateValue", "DecimalValue", "DoubleValue", "IntValue", "MetadataId", "RowId", "StringValue")
VALUES (null, 'c6c653c5-3fd3-4c54-ae0d-d5565b3cb725', '1', null, null, null, null, '-2', '1', 'asdf');
SELECT "Id"
FROM "UserReferencesData"
WHERE changes() = 1 AND "rowid" = last_insert_rowid();
If I switch to different table and then execute second query again it then pops a list of ids.
Upvotes: 2
Views: 388
Reputation: 9501
The problem has to do with naming, in particular RowId
.
public int RowId
{
get;
set;
}
changed it to RowKeyId
and it now works fine.
Upvotes: 1