33

我正在使用 Entity Framework Codefirst 来创建我的数据库。当我通过 ODBC 连接到 2007 时,具有模式名称 dbo.pk_Jobs 的默认主键似乎扰乱了 access 2007。如果我手动编辑名称并删除架构名称并将此主键重命名为 pk_jobs,Access 现在可以读取该表。

我可以使用 Fluent Api、数据属性或任何其他方法指定主键名称以不包含架构名称吗?

public class ReportsContext : DbContext
{
    public DbSet<Job> Jobs { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Job>().ToTable("Jobs");
        modelBuilder.Entity<Job>().HasKey(j => j.uuid);

        base.OnModelCreating(modelBuilder);
    }
}
public class Job
{
    public Guid uuid{ get; set; }
    public int active{ get; set; }
}
4

5 回答 5

61

如果要指定列名并覆盖属性名,可以尝试以下操作:

使用注解

public class Job
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Column("CustomIdName")]
    public Guid uuid { get; set; }
    public int active { get; set; }
}

使用代码优先

    protected override void OnModelCreating(DbModelBuilder mb)
    {
        base.OnModelCreating(mb);

        mb.Entity<Job>()
            .HasKey(i => i.uuid);
        mb.Entity<Job>()
          .Property(i => i.uuid)
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
          .HasColumnName("CustomIdName");
    }

内部迁移配置

public partial class ChangePrimaryKey : DbMigration
{
    public override void Up()
    {
        Sql(@"exec sp_rename 'SchemaName.TableName.IndexName', 'New_IndexName', 'INDEX'");
    }

    public override void Down()
    {
        Sql(@"exec sp_rename 'SchemaName.TableName.New_IndexName', 'Old_IndexName', 'INDEX'");
    }
}
于 2012-11-28T18:52:46.493 回答
8

您可以使用Key属性来指定主键的各个部分。所以你的工作类可能是

public class Job
{
    [Key]
    public Guid uuid{ get; set; }
    public int active{ get; set; }
}

数据注释属性在System.ComponentModel.DataAnnotations 命名空间中定义

于 2012-11-28T16:31:55.597 回答
2

如果我理解,您是在问如何更改实体框架使用的主键列的名称。您的 HasKey 语句中的以下添加应解决此问题:

modelBuilder.Entity<Job>().Property(j => j.uuid).HasColumnName("pk_Jobs")
于 2012-11-28T16:39:03.223 回答
1

(这是对@Jeff Sivers 和@cubski 的回答/评论的补充。)

据我所知,您无法使用数据属性指定 PK 名称。有时我需要去掉dbo.名称的一部分,然后使用手动编辑的代码先迁移来更改名称,如下所示:

public partial class ChangeNameOnPKInCustomers : DbMigration
{
    private static string fromName = "PK_dbo.Customers";    // Name to change

    private static string toName = fromName.Replace("dbo.", "");

    public override void Up()
    {
        Sql($"exec sp_rename @objname=N'[dbo].[{fromName}]', @newname=N'{toName}'");
        // Now the PK name is "PK_Customers".
    }

    public override void Down()
    {
        Sql($"exec sp_rename @objname=N'[dbo].[{toName}]', @newname=N'{fromName}'");
        // Back to "PK_dbo.Customers".
    }
}
于 2016-05-17T07:43:28.483 回答
0

当您使用 Code First 添加显式迁移时,您将获得一个带有迁移名称的 .cs 文件,该文件是具有基类 DbMigration 的部分类。

对于您的主键约束,您可以使用 DropPrimaryKey 或 AddPrimaryKey 函数,具体取决于您要执行的操作。我的问题是 DropPrimaryKey 因为我的 Db 的主键名称不同。

这两个函数都有重载来获取 PK 的名称,以便您可以显式指定 PK 的名称。对于具有显式 PK 名称的 DropPrimaryKey 对我来说效果很好。参数是对象 anonymousArguments,默认为 null。

于 2016-09-26T16:03:19.547 回答