首先在实体框架代码中,如何在多个列上使用KeyAttribute


93

我正在创建一个POCO模型,以便首先与实体框架代码一起使用。我正在使用装饰使属性映射到PK列。但是,如何在多于一个的列上定义PK,特别是如何控制索引中列的顺序?这是类中属性顺序的结果吗?

谢谢!

Answers:


153

您可以在属性中指定列顺序,例如:

public class MyEntity
{
    [Key, Column(Order=0)]
    public int MyFirstKeyProperty { get; set; }

    [Key, Column(Order=1)]
    public int MySecondKeyProperty { get; set; }

    [Key, Column(Order=2)]
    public string MyThirdKeyProperty { get; set; }

    // other properties
}

如果您使用a的Find方法,则DbSet必须考虑此顺序以获取关键参数。


1
InvalidOperationException:实体类型“ XXX”具有使用数据注释定义的复合主键。要设置复合主键,请使用fluent API。
卡·齐格勒

55

要完成Slauma提交的正确答案,您还可以使用HasKey方法来指定复合主键的顺序:

public class User
{        
    public int UserId { get; set; }       
    public string Username { get; set; }        
}        

public class Ctp5Context : DbContext
{
    public DbSet<User> Users { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasKey(u => new 
        { 
            u.UserId, 
            u.Username 
        });
    }
}

2
谢谢-两种方法都能正常工作。我更喜欢Attributes,因为我是从代码生成类的,而属性则更为简洁。
GilShalit 2011年

我还亲自将Propety(x ...)。HasColumnOrder(0 ... n)添加到每个键控属性。那好,坏,冷漠吗?
Suamere 2015年

7

如果像我一样喜欢使用配置文件,则可以通过这种方式进行配置(基于Manavi的示例):

public class User
{
    public int UserId { get; set; }
    public string Username { get; set; }
}  

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        ToTable("Users");
        HasKey(x => new {x.UserId, x.Username});
    }
}

显然,您必须将配置文件添加到上下文中:

public class Ctp5Context : DbContext
{
    public DbSet<User> Users { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         modelBuilder.Configurations.Add(new UserConfiguration());
    }
}

0

用作匿名对象:

modelBuilder.Entity<UserExamAttemptQuestion>().ToTable("Users").HasKey(o => new { o.UserId, o.Username }); 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.