simpleidserver / EFCore.Cassandra

Entity Framework Core provider for Cassandra
Apache License 2.0
35 stars 16 forks source link

using of DbContext.SaveChangesAsync() occurs an inner exception (v2.0.0) #8

Closed mpan2014 closed 4 years ago

mpan2014 commented 4 years ago

When I use the async save method of the DbContext following exception occurs. This happens after adding, updating or removing entities. Is this a bug or a new feature?

Cassandra.InvalidQueryException: there were 1 markers(?) in CQL but 0 bound variables at Cassandra.Tasks.TaskHelper.WaitToComplete(Task task, Int32 timeout) at Cassandra.Tasks.TaskHelper.WaitToCompleteWithMetrics(IMetricsManager manager, Task task, Int32 timeout) at Cassandra.Tasks.TaskHelper.WaitToCompleteWithMetrics[T](IMetricsManager manager, Task1 task, Int32 timeout) at Cassandra.Session.Execute(IStatement statement, String executionProfileName) at Cassandra.Session.Execute(IStatement statement) at Cassandra.Data.CqlCommand.ExecuteNonQuery() at Cassandra.Data.CqlBatchTransaction.Commit() at Microsoft.EntityFrameworkCore.Storage.RelationalTransaction.Commit() at Microsoft.EntityFrameworkCore.Cassandra.Update.Internal.CassandraBatchExecutor.ExecuteAsync(DbContext , ValueTuple2 parameters, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext , Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) ...`

simpleidserver commented 4 years ago

Can you copy the code you are trying to execute ?

mpan2014 commented 4 years ago

Sure:

public class DummiesWriteRepository : BaseWriteRepository, IDummiesWriteRepository
{
    public DummiesWriteRepository(WriteStoreDbContext dbContext, IWriteStoreMappingService mapper) 
        : base(dbContext, mapper)
    {
    }

    public async Task DeleteAsync(Dummy item)
    {
        var found = await DbContext
            .Dummies
            .Where(i => i.Id == item.Id)
            .FirstOrDefaultAsync().ConfigureAwait(false);
        if (found != null)
        {
            DbContext.Dummies.Remove(found);
            await DbContext.SaveChangesAsync().ConfigureAwait(false); => Here is where the exception is thrown
        }
    }
    public async Task<Dummy> GetByIdAsync(Guid id)
    {
        var foundList = await DbContext
            .Dummies
            .Where(x => x.Id == id)
            .ToListAsync().ConfigureAwait(false);
        if (foundList != null && foundList.Count > 0)
        {
            return Mapper.MapToDomain(foundList[0]);;
        }
        return null;
    }
    public async Task StoreAsync(Dummy item)
    {
        var document = Mapper.MapToDocument(item);
        var foundItem = await GetByIdAsync(document.Id).ConfigureAwait(false);
        if (foundItem == null)
        {
            DbContext.Dummies.Add(document);
        }
        else
        {
            // _dbContext.Entry(item).State = EntityState.Modified;
            DbContext.Update(document);
        }

        await DbContext.SaveChangesAsync().ConfigureAwait(false); => Here is where the exception is thrown
    }
}
public sealed class WriteStoreDbContext : DbContext
{
        private readonly IWriteStoreConfig _config;
        private readonly int _replicationFactor;
        private const int DefaultReplicationFactor = 1;

        public WriteStoreDbContext(IWriteStoreConfig config) 
        {
            _config = config;
            _replicationFactor = DefaultReplicationFactor;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // optionsBuilder.UseCassandra("Contact Points=127.0.0.1;", opt =>
            optionsBuilder.UseCassandra(_config.ConnectionString, opt =>
            {
                opt.MigrationsHistoryTable(HistoryRepository.DefaultTableName, _config.DbName);
            });
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ForCassandraAddKeyspace(_config.DbName, new KeyspaceReplicationSimpleStrategyClass(_replicationFactor));

            modelBuilder.Entity<DummyDocument>()
                .ToTable("dummies", _config.DbName)
                .HasKey(p => new { p.Id });
        }

        public DbSet<DummyDocument> Dummies { get; set; }
}
simpleidserver commented 4 years ago

We tried to reproduce your bug without success, can you please transfer your Visual Studio solution ? (the code above is working with the version 2.0.0). We are going to take a look to your issue.

mpan2014 commented 4 years ago

I've prepared as simple app where you can reproduce the issue. Post a request to the http://localhost:5000/dummies/ endpoint to start the process. (I've used Postman for this)

WebApplication.zip

simpleidserver commented 4 years ago

The issue is fixed, can you please try again with the release number 2.0.1 ? https://www.nuget.org/packages/EFCore.Cassandra

mpan2014 commented 4 years ago

Now everything works fine. Thanks!