我有一个POCO模型,其主键属性映射到具有不同名称的列。
该模型类似于:
public class Transaction
{
public long Id { get; set; }
//....more props
}
因此迁移看起来像:
CreateTable(
"dbo.dtlTransactions",
c => new
{
Id = c.Long(nullable: false, identity: true, name: "intTransactionID"),
//...more cols
})
.PrimaryKey(t => t.Id);
然而,在运行迁移时,我得到:
System.Data.SqlClient.SqlException(0x80131904):列名'Id' 目标表或视图中不存在。
在生成sql时似乎没有使用columnbuilder的name属性。迁移的-verbose选项为我提供了这个sql:
CREATE TABLE [dbo].[dtlTransactions] (
[intTransactionID] [bigint] NOT NULL IDENTITY,
--...other cols
CONSTRAINT [PK_dbo.dtlTransactions] PRIMARY KEY ([Id])
有什么想法吗?这是一个明显的错误吗?
答案 0 :(得分:2)
为了告诉实体框架EF将生成的SQL查询的列名,您必须为模型指定它,而不是在迁移中指定数据注释......
[Column("intTransactionID")]
public long Id { get; set; }
...或使用Fluent API:
modelBuilder.Entity<Transaction>()
.Property(t => t.Id)
.HasColumnName("intTransactionID");
以这种方式定义列名后,您不再需要在迁移代码中定义它。
您正在使用的Migration类中的name
参数会影响发送到数据库的DDL脚本,但不会告诉EF模型元数据该列具有其他名称。
老实说,我不知道任何用例,迁移代码中的name
参数可能有用。
修改强>
我已经测试过它可以使用以下示例:
我用你的班级:
public class Transaction
{
public long Id { get; set; }
}
在此上下文中,我使用Fluent API定义列名:
public class MyContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Transaction>()
.ToTable("dtlTransactions");
modelBuilder.Entity<Transaction>()
.Property(t => t.Id)
.HasColumnName("intTransactionID");
}
}
然后我在包管理器控制台上运行enable-migrations
和add-migration InitialSchema
。
我得到了这个DbMigration
课程:
public partial class InitialSchema : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.dtlTransactions",
c => new
{
intTransactionID = c.Long(nullable: false, identity: true),
})
.PrimaryKey(t => t.intTransactionID);
}
public override void Down()
{
DropTable("dbo.dtlTransactions");
}
}
然后我在包管理器控制台上调用update-database -script
并获取该表的DDL脚本 - 这是正确且预期的脚本:
CREATE TABLE [dbo].[dtlTransactions] (
[intTransactionID] [bigint] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.dtlTransactions] PRIMARY KEY ([intTransactionID])
)
答案 1 :(得分:0)
这似乎确实是EF Migrations API中的一个错误,正如此处所证实的那样:
答案 2 :(得分:0)
我使用两种映射选项(流畅和属性)进行了测试。在这两种情况下,使用Add-Migration生成迁移时,任何自定义映射都将被完全忽略。
映射有效,但迁移不起作用。这意味着在将EF用作ORM时,迁移不可用。
一种解决方法是手动制作迁移,而不是使用 TableBuilder ,使用 DbMigration 方法:
而不是
CreateTable(
"dbo.dtlTransactions",
c => new
{
Id = c.Long(nullable: false, identity: true, name: "intTransactionID"),
//...more cols
})
.PrimaryKey(t => t.Id, name: "intTransactionID");
你可以使用:
CreateTable(
"dbo.dtlTransactions",
c => new
{
Id = c.Long(nullable: false, identity: true, name: "intTransactionID"),
//...more cols
});
AddPrimaryKey("dbo.dtlTransactions", "intTransactionId");
TableBuilder.Index()也是如此 - 而不是使用CreateIndex()。