EntityFramework-Plus icon indicating copy to clipboard operation
EntityFramework-Plus copied to clipboard

Bulk update does not work when targeting AWS Aurora/MySql

Open paya-cz opened this issue 5 years ago • 2 comments

Description

I am running a code connecting to AWS Aurora cluster, running a MySql engine v5.6.10a.

This is how I set up a connection to the server:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    // See https://mysql-net.github.io/MySqlConnector/connection-options/ for more info
    var connectionStringBuilder = new MySqlConnectionStringBuilder
    {
        Server = Helper.DatabaseEndpoint,
        Port = 3306,
        Pooling = true,
        UserID = Helper.DatabaseUser,
        Password = Helper.DatabasePassword,
        SslMode = MySqlSslMode.VerifyCA,
        CACertificateFile = Path.Combine(Environment.CurrentDirectory, "Certificates", "rds-combined-ca-bundle.pem"),
        ConvertZeroDateTime = true
    };

    optionsBuilder
        .UseMySql(connectionStringBuilder.ConnectionString);
}

Then, I set up model for 2 different entities, that go into tables in 2 different schema. Eg. entityA into schemaA, and entityB goes into schemaB. Running the bulk update statement throws a MySql.Data.MySqlClient.MySqlException with message "No database selected", even though the entity has been configured via .ToTable(tableName, schema) to target a specific schema. The code doing the update is pretty much equivalent to:

ctx.entityA.Where(x => listOfIDs.Contains(x.Id))
    .Update(x => new EntityA() { SomeProperty = null });

Note that a similar code needs to be available for entityB also.

However, if I modify the MySqlConnectionStringBuilder to also include Database property, such as:


protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    // See https://mysql-net.github.io/MySqlConnector/connection-options/ for more info
    var connectionStringBuilder = new MySqlConnectionStringBuilder
    {
        Server = Helper.DatabaseEndpoint,
        Port = 3306,
        Database = schemaB
        Pooling = true,
        UserID = Helper.DatabaseUser,
        Password = Helper.DatabasePassword,
        SslMode = MySqlSslMode.VerifyCA,
        CACertificateFile = Path.Combine(Environment.CurrentDirectory, "Certificates", "rds-combined-ca-bundle.pem"),
        ConvertZeroDateTime = true
    };

    optionsBuilder
        .UseMySql(connectionStringBuilder.ConnectionString);
}

Then calling the Update code as above yields a different exception: MySql.Data.MySqlClient.MySqlException Message: Table 'schemaB.entityA_table` doesn't exist

At this point, it's pretty clear that EFPlus is just taking whatever is in the connection string builder's Database property, and using that as a schema when making calls. It seems EFPlus is completely ignoring schema defined by ModelBuilder's .ToTable.

I confirmed this theory by modifying the ConnectionStringBuilder to use: Database = schemaA At which point the .Update call works as expected.

Further technical details

  • EF version: EF Core v2.2.4
  • EF Plus version: 1.8.27
  • EF Provider: Pomelo.EntityFrameworkCore.MySql v2.2.0
  • Database: AWS Aurora cluster, MySql engine v.5.6.10a

paya-cz avatar May 02 '19 10:05 paya-cz

Hello @paya-cz ,

Our library should take what is stored in the relation table name: https://github.com/zzzprojects/EntityFramework-Plus/blob/master/src/shared/Z.EF.Plus.BatchUpdate.Shared/BatchUpdate.cs#L830

Is this issue can be reproduced using directly MySQL? We don't have any AWS Aurora clusted for testing.

JonathanMagnan avatar May 02 '19 23:05 JonathanMagnan

@JonathanMagnan The thing is, this is not about table name, but schema name. The code you showed just retrieves table name. But you can specify schema name also via .ToTable method, as shown here:

https://docs.microsoft.com/en-us/ef/core/modeling/relational/tables https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationalentitytypebuilderextensions.totable?view=efcore-2.1

This is what I'm using and what seems to be causing issue.

Also, I had issues using Owned entities, seems like this is not supported by EFPlus either? Basically when I was doing a bulk update on an entity that owns another entity, the generated SQL contained duplicate column for the master entity's primary key. Owned entities are supported since EFCore 2.0, maybe this is not yet supported in EFPlus?

paya-cz avatar May 03 '19 04:05 paya-cz