EF Code First 迁移不编译
EF Code First Migration doesn't compile
我正在使用 EF Code First 生成我的数据库架构(EF 6、.NET 4.5.2)。我有两个 类 我要插入:
public class MatrixFile
{
[Key]
public int Id { get; set; }
public string FilePath { get; set; }
public virtual List<MatrixData> Data { get; set; }
}
public class MatrixData
{
[Key]
public int Id { get; set; }
public int OdPairKey { get; set; }
public double Value { get; set; }
}
这是我的 DbContext
public class MyDataContext : DbContext
{
public virtual DbSet<MatrixFile> MatrixFiles { get; set; }
public virtual DbSet<MatrixData> MatrixData { get; set; }
}
我尝试通过在包管理器控制台中键入以下命令在 EF 中生成我的数据库模式:
Enable-Migrations
Add-Migration GenerateDatabase
这是 EF 为我生成的迁移:
public partial class GenerateDatabase : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.MatrixDatas",
c => new
{
Id = c.Int(nullable: false, identity: true),
OdPairKey = c.Int(nullable: false),
Value = c.Double(nullable: false),
MatrixFile_Id = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.MatrixFiles", t => t.MatrixFile_Id)
.Index(t => t.MatrixFile_Id, name: ""IX_MatrixData_MatrixFile_Id"");
CreateTable(
"dbo.MatrixFiles",
c => new
{
Id = c.Int(nullable: false, identity: true),
FilePath = c.String(),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropForeignKey("dbo.MatrixDatas", "MatrixFile_Id", "dbo.MatrixFiles");
DropIndex("dbo.MatrixDatas", ""IX_MatrixData_MatrixFile_Id"");
DropTable("dbo.MatrixFiles");
DropTable("dbo.MatrixDatas");
}
}
行 .Index(t => t.MatrixFile_Id, name: ""IX_MatrixData_MatrixFile_Id"");
由于 IX_MatrixData_MatrixFile_Id
周围的双引号而出现编译错误。为什么会这样?如何在不手动破解迁移的情况下让它生成正确的迁移代码?
你是对的钱@MichaelCoxon。我的目的是最终将它与 SQLite 一起使用,并且我安装了 SQLite.CodeFirst
包,因此我可以使用它来初始化数据库。我在 DataContext 中有以下代码:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<EngineDataContext>(modelBuilder);
Database.SetInitializer(sqliteConnectionInitializer);
}
似乎生成了流氓代码。删除它/将其注释掉可以解决问题。我不知道 OnModelCreating
会影响 EF 生成的代码!
为了进一步解释我对 OP 的评论,EF 在迁移脚手架中有这个...
// System.Data.Entity.Migrations.Design.CSharpMigrationCodeGenerator
/// <summary>
/// Quotes an identifier using appropriate escaping to allow it to be stored in a string.
/// </summary>
/// <param name="identifier"> The identifier to be quoted. </param>
/// <returns> The quoted identifier. </returns>
protected virtual string Quote(string identifier)
{
return "\"" + identifier + "\"";
}
...由 table 脚手架和索引脚手架调用。这会将代码生成为要写入 .cs 文件的字符串...
// System.Data.Entity.Migrations.Design.CSharpMigrationCodeGenerator
private void WriteIndexParameters(CreateIndexOperation createIndexOperation, IndentedTextWriter writer)
{
if (createIndexOperation.IsUnique)
{
writer.Write(", unique: true");
}
if (createIndexOperation.IsClustered)
{
writer.Write(", clustered: true");
}
if (!createIndexOperation.HasDefaultName)
{
writer.Write(", name: ");
writer.Write(this.Quote(createIndexOperation.Name));
}
}
问题是,如果 idenitifier
是 "\"IX_MYIndex\""
,您将在代码中得到引号 unescaped。您真正需要的是 - 如果您出于任何原因需要引号 "\\"IX_MYIndex\\""
以便转义序列在 C# 中有效。
我正在使用 EF Code First 生成我的数据库架构(EF 6、.NET 4.5.2)。我有两个 类 我要插入:
public class MatrixFile
{
[Key]
public int Id { get; set; }
public string FilePath { get; set; }
public virtual List<MatrixData> Data { get; set; }
}
public class MatrixData
{
[Key]
public int Id { get; set; }
public int OdPairKey { get; set; }
public double Value { get; set; }
}
这是我的 DbContext
public class MyDataContext : DbContext
{
public virtual DbSet<MatrixFile> MatrixFiles { get; set; }
public virtual DbSet<MatrixData> MatrixData { get; set; }
}
我尝试通过在包管理器控制台中键入以下命令在 EF 中生成我的数据库模式:
Enable-Migrations
Add-Migration GenerateDatabase
这是 EF 为我生成的迁移:
public partial class GenerateDatabase : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.MatrixDatas",
c => new
{
Id = c.Int(nullable: false, identity: true),
OdPairKey = c.Int(nullable: false),
Value = c.Double(nullable: false),
MatrixFile_Id = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.MatrixFiles", t => t.MatrixFile_Id)
.Index(t => t.MatrixFile_Id, name: ""IX_MatrixData_MatrixFile_Id"");
CreateTable(
"dbo.MatrixFiles",
c => new
{
Id = c.Int(nullable: false, identity: true),
FilePath = c.String(),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropForeignKey("dbo.MatrixDatas", "MatrixFile_Id", "dbo.MatrixFiles");
DropIndex("dbo.MatrixDatas", ""IX_MatrixData_MatrixFile_Id"");
DropTable("dbo.MatrixFiles");
DropTable("dbo.MatrixDatas");
}
}
行 .Index(t => t.MatrixFile_Id, name: ""IX_MatrixData_MatrixFile_Id"");
由于 IX_MatrixData_MatrixFile_Id
周围的双引号而出现编译错误。为什么会这样?如何在不手动破解迁移的情况下让它生成正确的迁移代码?
你是对的钱@MichaelCoxon。我的目的是最终将它与 SQLite 一起使用,并且我安装了 SQLite.CodeFirst
包,因此我可以使用它来初始化数据库。我在 DataContext 中有以下代码:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<EngineDataContext>(modelBuilder);
Database.SetInitializer(sqliteConnectionInitializer);
}
似乎生成了流氓代码。删除它/将其注释掉可以解决问题。我不知道 OnModelCreating
会影响 EF 生成的代码!
为了进一步解释我对 OP 的评论,EF 在迁移脚手架中有这个...
// System.Data.Entity.Migrations.Design.CSharpMigrationCodeGenerator
/// <summary>
/// Quotes an identifier using appropriate escaping to allow it to be stored in a string.
/// </summary>
/// <param name="identifier"> The identifier to be quoted. </param>
/// <returns> The quoted identifier. </returns>
protected virtual string Quote(string identifier)
{
return "\"" + identifier + "\"";
}
...由 table 脚手架和索引脚手架调用。这会将代码生成为要写入 .cs 文件的字符串...
// System.Data.Entity.Migrations.Design.CSharpMigrationCodeGenerator
private void WriteIndexParameters(CreateIndexOperation createIndexOperation, IndentedTextWriter writer)
{
if (createIndexOperation.IsUnique)
{
writer.Write(", unique: true");
}
if (createIndexOperation.IsClustered)
{
writer.Write(", clustered: true");
}
if (!createIndexOperation.HasDefaultName)
{
writer.Write(", name: ");
writer.Write(this.Quote(createIndexOperation.Name));
}
}
问题是,如果 idenitifier
是 "\"IX_MYIndex\""
,您将在代码中得到引号 unescaped。您真正需要的是 - 如果您出于任何原因需要引号 "\\"IX_MYIndex\\""
以便转义序列在 C# 中有效。