如何在实体框架4代码中首先映射复合主键?

时间:2022-03-15 02:09:37

I'm getting to grips with EF4 code first, and liking it so far. But I'm having trouble mapping an entity to a table with a composite primary key.

我首先接触到EF4代码,到目前为止我很喜欢它。但是我在用复合主键将实体映射到表时遇到了麻烦。

The configuration I've tried looks like this:

我试过的配置是这样的:

public SubscriptionUserConfiguration()

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

Which throws this exception: Unable to infer a key for entity type 'SubscriptionUser'.

这将引发此异常:无法推断实体类型“SubscriptionUser”的键。

What am I missing?

我缺少什么?

4 个解决方案

#1


69  

You could also use

您还可以使用

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

Edit:

编辑:

One limitation I have found is that the following do not work:

我发现的一个局限性是,以下方法不起作用:

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

or

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

So how do you set up an entity where the join table has a primary key that is composed of foreign keys?

那么如何设置一个实体,使联接表具有由外键组成的主键?

#2


20  

I will try to explain it step by step, using the following Entity

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

public class Account
{
    public int AccountId1 { get; set; }
    public int AccountId2 { get; set; }
    public string Description { get; set; }
}
  1. Create a class derived from the EntityTypeConfiguaration<TEntity> Object to override the conventions

    创建一个派生自EntityTypeConfiguaration 对象的类,以覆盖这些约定

    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. When create the class derived from the DbContext Object, override OnModelCreating Method and add a new AccountEntityTypeConfiguration object to the Configurations of the model Builder.

    当创建从DbContext对象派生的类时,重写onmodelcreation方法,并向模型构建器的配置添加一个新的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());
        }
    
    }
    

Hope it helps you!

希望它能帮助你!

#3


14  

You can also use the Column attribute

您还可以使用Column属性

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

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

#4


6  

Solved it: I should be using HasKey, not Identity. This works:

解决它:我应该使用HasKey,而不是Identity。如此:

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

#1


69  

You could also use

您还可以使用

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

Edit:

编辑:

One limitation I have found is that the following do not work:

我发现的一个局限性是,以下方法不起作用:

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

or

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

So how do you set up an entity where the join table has a primary key that is composed of foreign keys?

那么如何设置一个实体,使联接表具有由外键组成的主键?

#2


20  

I will try to explain it step by step, using the following Entity

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

public class Account
{
    public int AccountId1 { get; set; }
    public int AccountId2 { get; set; }
    public string Description { get; set; }
}
  1. Create a class derived from the EntityTypeConfiguaration<TEntity> Object to override the conventions

    创建一个派生自EntityTypeConfiguaration 对象的类,以覆盖这些约定

    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. When create the class derived from the DbContext Object, override OnModelCreating Method and add a new AccountEntityTypeConfiguration object to the Configurations of the model Builder.

    当创建从DbContext对象派生的类时,重写onmodelcreation方法,并向模型构建器的配置添加一个新的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());
        }
    
    }
    

Hope it helps you!

希望它能帮助你!

#3


14  

You can also use the Column attribute

您还可以使用Column属性

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

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

#4


6  

Solved it: I should be using HasKey, not Identity. This works:

解决它:我应该使用HasKey,而不是Identity。如此:

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