w kodzie struktury jednostki, jak używać KeyAttribute w wielu kolumnach

95

Tworzę model POCO do użycia z kodem struktury jednostki najpierw CTP5. Używam dekoracji, aby stworzyć mapę właściwości na kolumnę PK. Ale jak mogę zdefiniować PK w więcej niż jednej kolumnie, a konkretnie, jak mogę kontrolować kolejność kolumn w indeksie? Czy wynika to z kolejności właściwości w klasie?

Dzięki!

GilShalit
źródło

Odpowiedzi:

155

Możesz określić kolejność kolumn w atrybutach, na przykład:

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
}

Jeśli używasz Find metody a DbSet, musisz wziąć pod uwagę tę kolejność dla kluczowych parametrów.

Slauma
źródło
1
InvalidOperationException: typ jednostki „XXX” ma złożony klucz podstawowy zdefiniowany z adnotacjami danych. Aby ustawić złożony klucz podstawowy, użyj interfejsu API Fluent.
Luca Ziegler
57

Aby uzupełnić poprawną odpowiedź przesłaną przez Slaumę, możesz użyć metody HasKey , aby określić kolejność również złożonych kluczy głównych:

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 
        });
    }
}
Morteza Manavi
źródło
2
Dzięki - obie metody działają dobrze. Preferuję atrybuty, ponieważ generuję moje klasy z kodu, a atrybuty są znacznie bardziej zwięzłe.
GilShalit,
Osobiście dodaję również właściwość Propety (x ...). HasColumnOrder (0 ... n) do każdej z właściwości klucza. Czy to dobrze, źle, obojętnie?
Suamere
8

Jeśli tak jak ja wolisz użyć pliku konfiguracyjnego, możesz to zrobić w ten sposób (na podstawie przykładu Manaviego):

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});
    }
}

Oczywiście musisz dodać plik konfiguracyjny do swojego kontekstu:

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

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         modelBuilder.Configurations.Add(new UserConfiguration());
    }
}
Daniele Armanasco
źródło
0

Użyj jako anonimowego obiektu:

modelBuilder.Entity<UserExamAttemptQuestion>().ToTable("Users").HasKey(o => new { o.UserId, o.Username }); 
WACS kumara
źródło