web-dev-qa-db-fra.com

Comment mapper d'abord une clé primaire composite dans le code Entity Framework 4?

Je commence par me familiariser avec le code EF4 et je l'aime jusqu'à présent. Mais j'ai du mal à mapper une entité à une table avec une clé primaire composite.

La configuration que j'ai essayée ressemble à ceci:

public SubscriptionUserConfiguration()

    {
                Property(u => u.SubscriptionID).IsIdentity();
                Property(u => u.UserName).IsIdentity();
    }

Ce qui lève cette exception: impossible de déduire une clé pour le type d'entité "SubscriptionUser".

Qu'est-ce que je rate?

46
jamesfm

Vous pouvez également utiliser

HasKey(u => new { u.SubscriptionID, u.UserName });

Éditer:

Une limitation que j'ai trouvée est que les éléments suivants ne fonctionnent pas:

public ProjectAssignmentConfiguration()
{
    HasKey(u => u.Employee.EmployeeId);
    HasKey(u => u.Project.ProjectId);
}

ou

public ProjectAssignmentConfiguration()
{
    HasKey(u => new { u.Employee.EmployeeId, u.Project.ProjectId });
}

Alors, comment configurer une entité où la table de jointure a une clé primaire composée de clés étrangères?

73
djskinner

Je vais essayer de l'expliquer étape par étape, en utilisant l'entité suivante

public class Account
{
    public int AccountId1 { get; set; }
    public int AccountId2 { get; set; }
    public string Description { get; set; }
}
  1. Créez une classe dérivée de EntityTypeConfiguaration<TEntity> Objet pour outrepasser les conventions

    class AccountEntityTypeConfiguration : EntityTypeConfiguration<Account>
    {
    
        public AccountEntityTypeConfiguration()
        {
          // The Key
          // The description of the HasKey Method says
          // A lambda expression representing the property to be used as the primary key.
          // If the primary key is made up of multiple properties then specify an anonymous type including the properties.
          // Example C#: k => new { k.Id1, k.Id2 }
          // Example VB: Function(k) New From { k.Id1, k.Id2 }
          this.HasKey(k => new { k.AccountId1, k.AccountId2 } );  // The Key
    
          // Maybe the key properties are not sequenced and you want to override the conventions
          this.Property(p => p.AccountId1).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
          this.Property(p => p.AccountId2).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
    
          this.Property(p => p.Description).IsRequired();  // This property will be required
          this.ToTable("Account");  // Map the entity to the table Account on the database
        }
    }
    
  2. Lorsque vous créez la classe dérivée de l'objet DbContext, remplacez la méthode OnModelCreating et ajoutez un nouvel objet AccountEntityTypeConfiguration aux configurations du générateur de modèle.

    public class MyModelAccount : DbContext
    {
        public DbSet<Account> Accounts { get; set;}
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Add a new AccountEntityTypeConfiguration object to the configuration of the model, that will be applied once the model is created. 
            modelBuilder.Configurations.Add(new AccountEntityTypeConfiguration());
        }
    
    }
    

J'espère que cela vous aide!

20
sergioacortes

Vous pouvez également utiliser l'attribut Column

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

    [Key, Column(Order = 1)]
    public int RoleId { get; set; }
}
15
Aaron Hoffman

Résolu: je devrais utiliser HasKey, pas Identity. Cela marche:

public SubscriptionUserConfiguration()
{
     HasKey(u => u.SubscriptionID);
     HasKey(u => u.UserName);
}
6
jamesfm