多少事,从来急,天地转,光阴迫,一万年太久|

Ak.Ini

园龄:14年3个月粉丝:12关注:10

解决 Mysql下使用EF Code First 指定表Engine无效的思路

用Code First创建表时 用 update-database -verbose 查看脚本 可以发现所有的表的默认Engine都是InnoDB

因为业务要求 有张表的Engine是MyISAM.

到Migration的up方法中修改

未修改前的代码如下:

CreateTable(
    "Tests",
    c => new
        {
            ID = c.Int(nullable: false),
            Name = c.String(unicode: false),
    })
    .PrimaryKey(t => t.ID);

想办法从CreateTable方法入手 查看基类CreateTable方法说明

//
        // 摘要:
        //     Adds an operation to create a new table.
        //
        // 参数:
        //   name:
        //     The name of the table. Schema name is optional, if no schema is specified
        //     then dbo is assumed.
        //
        //   columnsAction:
        //     An action that specifies the columns to be included in the table.  i.e. t
        //     => new { Id = t.Int(identity: true), Name = t.String() }
        //
        //   anonymousArguments:
        //     Additional arguments that may be processed by providers. Use anonymous type
        //     syntax to specify arguments e.g. 'new { SampleArgument = "MyValue" }'.
        //
        // 类型参数:
        //   TColumns:
        //     The columns in this create table operation. You do not need to specify this
        //     type, it will be inferred from the columnsAction parameter you supply.
        //
        // 返回结果:
        //     An object that allows further configuration of the table creation operation.
        protected internal TableBuilder<TColumns> CreateTable<TColumns>(string name, Func<ColumnBuilder, TColumns> columnsAction, object anonymousArguments = null);

好了 anonymousArguments参数是我可以用的 根据说明 本以为应该是 new { Engine = "MyISAM" }

修改代码后 如下:

CreateTable(
    "Tests",
    c => new
        {
            ID = c.Int(nullable: false),
            Name = c.String(unicode: false),
        }, new { Engine = "MyISAM" })
    .PrimaryKey(t => t.ID);

再update-database -verbose 看脚本 结果还是一样 默认InnoDB的 

当时估计 可能是PropertyName 区分大小写 又试了 new { engine = "MyISAM" } new { ENGINE = "MyISAM" }

还是不行. nnd mysql关于code first的资料太少了 官网上都是些简单的demo

没办法 去下载Connector的源码 自己看看 源码下载点击这里

打开项目MySql.Data.Entity中的MySqlMigrationSqlGenerator.cs

protected virtual MigrationStatement Generate(CreateTableOperation op)
{
  StringBuilder sb = new StringBuilder();
  if (generatedTables == null)
    generatedTables = new List<string>();
 
  if (!generatedTables.Contains(op.Name))
  {
    generatedTables.Add(op.Name);
  }
  sb.Append("create table " + "`" + op.Name + "`" + " (");
 
  //columns
  sb.Append(string.Join(",", op.Columns.Select(c => "`" + c.Name + "` " + Generate(c))));
 
  if (op.PrimaryKey != null && !sb.ToString().Contains("primary key"))
  {
    sb.Append(",");
    sb.Append("primary key ( " + string.Join(",", op.PrimaryKey.Columns.Select(c => "`" + c + "`")) + ") ");
  }
 
    sb.Append(") engine=InnoDb auto_increment=0");
 
    return new MigrationStatement() { Sql = sb.ToString() };
}

搞了半天 原来根本没有考虑到指定Engine的情况.

到这里就没办法继续了 我只是提供思路 修改源码

if (op.AnonymousArguments.ContainsKey("Engine"))
{
    sb.Append(string.Format(") engine={0} auto_increment=0", op.AnonymousArguments["Engine"]));
}
else
{
    sb.Append(") engine=InnoDb auto_increment=0");
}

然后再用 new { Engine = "MyISAM" }就没有问题了

稍后我会向mysql 提交bug报告 各位同学也可以等待mysql来修复  

已经向mysql提交功能缺失bug报告 Bug #68237

 

本文作者:Ak.Ini

本文链接:https://www.cnblogs.com/akini/archive/2013/01/31/2887393.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Ak.Ini  阅读(1476)  评论(3编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起