Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot configure the database table name prefix when using EntityFramework with MySql #84

Closed
DillonHuang opened this issue Feb 7, 2018 · 10 comments

Comments

@DillonHuang
Copy link

commented Feb 7, 2018

我想要修改下Cap中表的前缀
使用如下代码:

capOptions.UseMySql(mysqlOptions =>
     {
           mysqlOptions.ConnectionString = "Server=192.168.69.177;Database=Dillon.Cap.Publisher;UserId=root;Password=Iubang001!;Allow User Variables=True";
           mysqlOptions.TableNamePrefix = "my.cap";
     });

以上代码报错如下:

If you are using the EntityFramework, you need to configure the DbContextType first. otherwise you >need to use overloaded method with IDbConnection and IDbTransaction.

这个应该是因为 MySqlOptions.DbContextType==null

但是MySqlOptions.DbContextType 作用域是 internal,没法直接赋值。
如果通过反射对MySqlOptions.DbContextType 就可以了

var dbContextType = typeof(EFOptions).GetProperty(
       "DbContextType",
       BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
       dbContextType.SetValue(mysqlOptions, typeof(AppDbContext));

用反射感觉不是很好,希望有更好的解决方案!

@yang-xiaodong

This comment has been minimized.

Copy link
Member

commented Feb 7, 2018

如果你是使用MySql + EntityFramework的话,是这样配置的

    services.AddDbContext<AppDbContext>();

    services.AddCap(x =>
    {
        x.UseEntityFramework<AppDbContext>();
        x.UseRabbitMQ("localhost");
    });

CAP会自动发现 AppDbContext 中使用的数据库以及连接字符串。

@yang-xiaodong

This comment has been minimized.

Copy link
Member

commented Feb 7, 2018

不好意思,我可能理解错你的意思了,等我看一下

@DillonHuang

This comment has been minimized.

Copy link
Author

commented Feb 7, 2018

我是想修改表的前缀
我试过用x.UseEntityFramework<AppDbContext>();修改表前缀也是不起作用的!
也只能通过反射来实现

capOptions.UseEntityFramework<AppDbContext>(
                        opts =>
                            {
                                if (opts is MySqlOptions mySqlOptions)
                                {
                                    var dbContextType = typeof(EFOptions).GetProperty(
                                          "DbContextType",
                                          BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                                    dbContextType.SetValue(opts, typeof(AppDbContext));
                                    mySqlOptions.TableNamePrefix = "my.cap";
                                }
                            });
@DillonHuang

This comment has been minimized.

Copy link
Author

commented Feb 7, 2018

看下源码这个方法:

 public static CapOptions UseEntityFramework<TContext>(this CapOptions options, Action<EFOptions> configure) where TContext : DbContext
    {
      if (configure == null)
        throw new ArgumentNullException(nameof (configure));
      EFOptions efOptions = new EFOptions()
      {
        DbContextType = typeof (TContext)
      };
      configure(efOptions);
      options.RegisterExtension((ICapOptionsExtension) new MySqlCapOptionsExtension((Action<MySqlOptions>) configure));
      return options;
    }

上面这段代码中的 efOptions 是局部变量,没有往下传递,这样DbContextType就丢失了。
只要掉要上面这个方法就会出问题

@yang-xiaodong

This comment has been minimized.

Copy link
Member

commented Feb 7, 2018

使用 EF 忘记开放重命名表的功能了,这块我可能要重构一下

@yang-xiaodong yang-xiaodong added enhancement and removed question labels Feb 7, 2018

@yang-xiaodong yang-xiaodong changed the title 修改MySqlOptions.TableNamePrefix不起作用 Cannot configure the database table name when using EntityFramework Feb 7, 2018

@yang-xiaodong yang-xiaodong changed the title Cannot configure the database table name when using EntityFramework Cannot configure the database table name prefix when using EntityFramework Feb 7, 2018

yang-xiaodong added a commit that referenced this issue Feb 8, 2018

@yang-xiaodong yang-xiaodong added the fixed label Feb 8, 2018

@yang-xiaodong

This comment has been minimized.

Copy link
Member

commented Feb 8, 2018

@tirongaws I have fixed this issue in version 2.1.4-preview-34825232.
You can configure the table name prefix like this:

services.AddDbContext<AppDbContext>();

services.AddCap(x =>
{
    x.UseEntityFramework<AppDbContext>(opt => opt.TableNamePrefix="xxx"); // xxx is your tabe name prefix.
    x.UseRabbitMQ("localhost");
});

Thanks for your report.

@yang-xiaodong yang-xiaodong changed the title Cannot configure the database table name prefix when using EntityFramework Cannot configure the database table name prefix when using EntityFramework with MySql Feb 8, 2018

@DillonHuang

This comment has been minimized.

Copy link
Author

commented Feb 8, 2018

看了下你最新的Commit,似乎没有解决问题。

1.  public static CapOptions UseEntityFramework<TContext>(this CapOptions options, Action<EFOptions> configure)
2.            where TContext : DbContext
3.        {
4.            if (configure == null) throw new ArgumentNullException(nameof(configure));
5.
6.            var efOptions = new EFOptions {DbContextType = typeof(TContext)};
7.            configure(efOptions);
8.
9.            options.RegisterExtension(new MySqlCapOptionsExtension(configure));
10.
11.            return options;
12.        }

第6、7行代码似乎没有意义,因为在MySqlCapOptionsExtension.AddServices中会new MySqlOptions()
然后再次调用config,代码如下:

internal class MySqlCapOptionsExtension : ICapOptionsExtension
    {
        private readonly Action<MySqlOptions> _configure;

        public MySqlCapOptionsExtension(Action<MySqlOptions> configure)
        {
            _configure = configure;
        }

        public void AddServices(IServiceCollection services)
        {
.............
            var mysqlOptions = new MySqlOptions();
            _configure(mysqlOptions);

            if (mysqlOptions.DbContextType != null)
.............
            else
                services.AddSingleton(mysqlOptions);
        }
    }

AddServicesvar mysqlOptions =new MySqlOptions()
此时mysqlOptions.DbContextType ==null,
虽然接下来调用了 _configure(mysqlOptions),但是DbContextTypeinternal作用域
_configure中没法正常赋值,理论上也不应该在_configure中对DbContextType进行赋值
所以就一直执行了代码 services.AddSingleton(mysqlOptions)

@yang-xiaodong

This comment has been minimized.

Copy link
Member

commented Feb 8, 2018

@tirongaws 你好,我已经修复了这个问题,你可以拉取一下最新代码,如果没有问题的话,我再发布一个Preview版本。

@DillonHuang

This comment has been minimized.

Copy link
Author

commented Feb 8, 2018

这么改应该可以了

@DillonHuang DillonHuang closed this Feb 8, 2018

@yang-xiaodong

This comment has been minimized.

Copy link
Member

commented Feb 8, 2018

fixed in version 2.1.4-preview-34848409

yang-xiaodong added a commit that referenced this issue Mar 16, 2018
Release version 2.1.4 (#97)
* Fixed the connection bug of getting message from table. #83

* update version to 2.1.4

* remove `TableNamePrefix` option from `MySqlOptions` to `EFOptions`.  #84

* fixed entityframework rename table name prefix bug.  #84

* fixed sql server scripts bug of create table scheme. #85

* fixed entityframework rename table name prefix bug. #84

* modify error message of logger write

* Fixed bug of the FailedRetryCount does not increase when raised SubscriberNotFoundException. #90

* Fixed thread safety issue about KafkaOptions. #89

* upgrade nuget package
yang-xiaodong added a commit that referenced this issue Aug 21, 2018
Release version 2.1.4 (#97)
* Fixed the connection bug of getting message from table. #83

* update version to 2.1.4

* remove `TableNamePrefix` option from `MySqlOptions` to `EFOptions`.  #84

* fixed entityframework rename table name prefix bug.  #84

* fixed sql server scripts bug of create table scheme. #85

* fixed entityframework rename table name prefix bug. #84

* modify error message of logger write

* Fixed bug of the FailedRetryCount does not increase when raised SubscriberNotFoundException. #90

* Fixed thread safety issue about KafkaOptions. #89

* upgrade nuget package
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.