Skip to content

Conversation

@rcdmk
Copy link
Contributor

@rcdmk rcdmk commented May 6, 2013

Added a MySqlBatchRunner to use batch UPDATEs and DELETEs with MySQL .Net Connector.

Sorry for me being lazy and not creating a test project for this. I've made various local tests with a simple 5 line console app and it works as expected.

Hope someone have some time to give a little more attention to it and maybe I can follow-up with a better contribution.

@quantumtunneling
Copy link

Why has this not been merged? Does loresoft have some issue with it?

@djechelon
Copy link
Contributor

Hi all,

one thing looks missing in this PR. The MySqlBatchRunner is not registered in the IoC Locator. Maybe developer has to set it at app startup (ugly) or, better, the IoC mechanism should be redesigned in order to pick the correct IBatchRunner according to the implementation of DbContext.Database.Connection.

But this adds a new problem: supporting different dialects (so we will end up with an OracleBatchRunner and a SQLiteBatchRunner eventually).

@rcdmk
Copy link
Contributor Author

rcdmk commented Apr 3, 2015

The way it was designed implies this kind of implementation. One implementatoin per dialect.
Including new dialects brings the need of changing the IoC Locator aswell, what I could not see at the time I was writing it.

There are any problem in this contribuition that makes it unusefull?

Update base project from lotesoft/master
@djechelon
Copy link
Contributor

@quantumtunneling looks like loresoft is not much active on this project anymore 😢

@damiangreen
Copy link

yes, i did email him and he did merge a bunch of tickets across, not the one i was hoping for unfortunately...

@djechelon
Copy link
Contributor

@rcdmk looks your PR has compilation problems. I have tried to fix them according to EF.E structure (async methods and #if statements). Not sure whether to PR to your fork or to the official (at least AppVeyor will check and test code). Maybe to both

@djechelon djechelon mentioned this pull request Jul 7, 2015
pwelter34 added a commit that referenced this pull request Jul 9, 2015
@pwelter34 pwelter34 merged commit 8b2f080 into zzzprojects:master Jul 9, 2015
@djechelon
Copy link
Contributor

Ok, the runner seems to be implemented. But now we must tell EF.E how to tell between SqlServer batch runner and MySql batch runner. Currently BatchExtensions.cs (https://github.com/loresoft/EntityFramework.Extended/blob/97806210a1014d0240d4740835b7e2c6e45b9438/Source/EntityFramework.Extended/Extensions/BatchExtensions.cs#L400) resolves the proper IBatchRunner to use based on ILocator.

ef e

This approach must be changed but I would like to ask for advice.

The method must take a System.Type object to determine the connection type or Entity Framework configuration (e.g.. If it is MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6) or even better the provider name (e.g. from App.config)

<providers>
  <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
  <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>

Now the advice I ask: if testing with is operator, MySql.Data.Entities must be brought into the project, but not everyone may want it. A less cleaner approach is to test the type name by magic strings.

I am preparing a code modification on my branch that does not use ILocator to determine the batch runner and works only with SQL Server for now.


Another activity is to write MySQL tests. They could derive from SQL Server (linked source)

@djechelon
Copy link
Contributor

An alternative might be introducing a configuration parameter in the appSettings section (but it must default to Sql Server to avoid breaking compatibility). This is risky because if in the future we need more parameters we might need to add an entire EntityFramework.Extended configuration section, which adds excessive complexity to the tool IMO 😢

@pwelter34
Copy link
Contributor

On application startup, call the following ...

Locator.Current.Register<IBatchRunner>(() => new MySqlBatchRunner());

@djechelon
Copy link
Contributor

What about auto detection? Applications, like mine, that need to switch between both DBs with simple Web.config transformations will benefit a lot

    private static IBatchRunner ResolveRunner(ObjectContext context)
    {
        DbConnection theConnection = (context.Connection as EntityConnection).StoreConnection;

        IBatchRunner provider = null;

        if (theConnection is SqlConnection)
            provider = new SqlServerBatchRunner();
        else if (theConnection.GetType().FullName == "MySql.Data.MySqlClient.MySqlConnection")
            provider = new MySqlBatchRunner();

        if (provider == null)
        {
            var ex = new InvalidOperationException("Could not resolve the IBatchRunner. Current database is not supported");
            ex.Data["DbConnection"] = theConnection;

            throw ex;
        }

        return provider;
    }

@djechelon
Copy link
Contributor

Returning to @rcdmk's work, I have another finding (as already reported by @shadowzcw): dbo is still present in queries. According to my investigation, this is because the MetadataMappingProvider takes into account the table schema, which is not part of MySql model. MySql supports only flat databases.

Replacing [dbo] is very dangerous because implementors can rightfully name "dbo" a table name or column (or a value of the query).

Surely if schema is null (which is correct in Mysql) we fixed it all. Maybe @shadowzcw comes, like me, from a database-first model?

@IDisposable
Copy link

I'm with @pwelter34 on this, but register the correct runner based on your inspection of the connection string.

Related fun http://stackoverflow.com/questions/20912406/sql-schema-changed-to-be-dbo-dbo-after-altering-table-name

@djechelon
Copy link
Contributor

Hi guys, I have successfully fixed the dbo issue with MySQL.

My solution was to store SchemaName property in the EntityMap class, then in the runner implementation (SQL Server or MySQL) choose whether to take the SchemaName into account or not. SQL Server will take and escape SchemaName.TableName (e.g. [dbo].[mytable]) while MySQL will only take TableName (e.g. mytable, backtick-escaped).

Currently my branch contains both this modification (already tested on the two DBs) and other modifications earlier proposed (e.g. auto detection of runner based on connection inspection).

I would like to push at least commit 4da2cad, but I'd ask for your comments also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

8 participants