如何首先在 Entity Framework 4 代码中映射复合主键?

Posted

技术标签:

【中文标题】如何首先在 Entity Framework 4 代码中映射复合主键?【英文标题】:How do I map a composite primary key in Entity Framework 4 code first? 【发布时间】:2011-02-13 13:33:23 【问题描述】:

我首先掌握了 EF4 代码,并且到目前为止我很喜欢它。但我无法将实体映射到具有复合主键的表。

我试过的配置是这样的:

public SubscriptionUserConfiguration()

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

抛出此异常: 无法推断实体类型“SubscriptionUser”的键。

我错过了什么?

【问题讨论】:

【参考方案1】:

我将尝试使用以下实体逐步解释它

public class Account

    public int AccountId1  get; set; 
    public int AccountId2  get; set; 
    public string Description  get; set; 

    创建一个派生自EntityTypeConfiguaration<TEntity> 对象的类以覆盖约定

    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
        
    
    

    创建派生自DbContext 对象的类时,覆盖OnModelCreating 方法并将新的AccountEntityTypeConfiguration 对象添加到模型生成器的配置中。

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

希望对你有帮助!

【讨论】:

【参考方案2】:

你也可以使用Column属性

public class UserProfileRole

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

    [Key, Column(Order = 1)]
    public int RoleId  get; set; 

【讨论】:

只是提醒那些搜索 - ColumnAttribute 需要 .NET 4.5【参考方案3】:

你也可以使用

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

编辑:

我发现的一个限制是以下不起作用:

public ProjectAssignmentConfiguration()

    HasKey(u => u.Employee.EmployeeId);
    HasKey(u => u.Project.ProjectId);

public ProjectAssignmentConfiguration()

    HasKey(u => new  u.Employee.EmployeeId, u.Project.ProjectId );

那么如何设置一个实体,其中连接表的主键由外键组成?

【讨论】:

刚刚遇到了同样的问题,我的症状是它返回了正确数量的实体,但是所有具有相同第一个键的实体都返回了第一条记录的数据内容,而忽略了第二条。我的插入似乎也做了一些有趣的事情,并插入了数据库中已经存在的其他记录的数据。 您可以将外键添加到实体上。例如,您可以将 Project 和 ProjectId 添加到父实体,而不是 u.Project.Id。【参考方案4】:

解决了:我应该使用 HasKey,而不是 Identity。这有效:

public SubscriptionUserConfiguration()

     HasKey(u => u.SubscriptionID);
     HasKey(u => u.UserName);

【讨论】:

或者可能需要使用丹尼尔建议的表格? ***.com/questions/3299268/… 不过,我假设它对你有用。

以上是关于如何首先在 Entity Framework 4 代码中映射复合主键?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Entity Framework Code First 中映射 sum 属性(如 TotalPrice)

如何使用Entity Framework 4.1 Code First为数据库中的一对多关系强制一对一关系

如何在 Entity Framework 4.4 中实现 DBSet.AddOrUpdate?

Entity Framework实体框架使用TrackerEnabledDbContext进行操作日志跟踪

如何在 Entity Framework 4.1 中使用更新 SPROC

在 Entity Framework 4.3 中增量播种数据的最佳方法