2

我有一个 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])

有任何想法吗?这是一个明显的错误吗?

4

3 回答 3

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])
    )
    
于 2013-08-26T18:02:59.073 回答
0

似乎这确实是 EF Migrations API 中的一个错误,正如在此处确认的那样:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/3868f5e7-144a-4212-9eb7-80a3b1e32fc2/entity-framework-migrations-primarykey#3868f5e7-144a-4212-9eb7-80a3b1e32fc2

于 2013-08-29T14:49:40.827 回答
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() 。

于 2013-08-30T10:42:22.143 回答