132

Sql服务器表:

SomeId PK varchar(50) not null 
OtherId PK int not null

我应该如何首先在 EF 6 代码中映射它?

public class MyTable
{
    [Key]
    public string SomeId { get; set; }

    [Key]
    public int OtherId { get; set; }
}

我看过一些例子,你必须为每列设置顺序,这是必需的吗?

某处有这方面的官方文件吗?

4

4 回答 4

217

您肯定需要按列顺序排列,否则 SQL Server 应该如何知道哪个排在前面?以下是您需要在代码中执行的操作:

public class MyTable
{
  [Key, Column(Order = 0)]
  public string SomeId { get; set; }

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

你也可以看看这个 SO question。如果您想要官方文档,我建议您查看官方 EF 网站。希望这可以帮助。

编辑:我刚刚发现 Julie Lerman 的一篇博客文章,其中包含各种 EF 6 优点的链接。你可以在这里找到你需要的任何东西。

于 2013-11-05T15:44:44.367 回答
61

对于使用实体框架映射复合主键,我们可以使用两种方法。

1)通过重写 OnModelCreating() 方法

例如:我有一个名为 VehicleFeature 的模型类,如下所示。

public class VehicleFeature
{
    public int VehicleId { get; set; }
    public int FeatureId{get;set;}
    public Vehicle Vehicle{get;set;}
    public Feature Feature{get;set;}
}

我的 DBContext 中的代码就像,

public class VegaDbContext : DbContext
{
    public DbSet<Make> Makes{get;set;}

    public DbSet<Feature> Features{get;set;}
    public VegaDbContext(DbContextOptions<VegaDbContext> options):base(options)        
    {           

    }
    // we override the OnModelCreating method here.
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<VehicleFeature>().HasKey(vf=> new {vf.VehicleId, vf.FeatureId});
    }
}

2)通过数据注释。

public class VehicleFeature
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]  
    [Key]
    public int VehicleId { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]   
    [Key]
    public int FeatureId{get;set;}
    public Vehicle Vehicle{get;set;}
    public Feature Feature{get;set;}
}

请参阅以下链接以获取更多信息。

1) https://msdn.microsoft.com/en-us/library/jj591617(v=vs.113).aspx

2)如何使用 EF 6 Fluent Api 添加复合唯一键?

于 2017-09-03T03:29:24.463 回答
9

我想我会添加到这个问题,因为它是顶级谷歌搜索结果。

正如评论中所指出的,在 EF Core 中不支持使用注释(关键属性),必须使用 fluent 来完成。

当我正在进行从 EF6 到 EF Core 的大规模迁移时,这很令人讨厌,因此我尝试通过使用反射来查找 Key 属性,然后在 OnModelCreating 期间应用它来破解它

// get all composite keys (entity decorated by more than 1 [Key] attribute
foreach (var entity in modelBuilder.Model.GetEntityTypes()
    .Where(t => 
        t.ClrType.GetProperties()
            .Count(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute))) > 1))
{
    // get the keys in the appropriate order
    var orderedKeys = entity.ClrType
        .GetProperties()
        .Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute)))
        .OrderBy(p => 
            p.CustomAttributes.Single(x => x.AttributeType == typeof(ColumnAttribute))?
                .NamedArguments?.Single(y => y.MemberName == nameof(ColumnAttribute.Order))
                .TypedValue.Value ?? 0)
        .Select(x => x.Name)
        .ToArray();

    // apply the keys to the model builder
    modelBuilder.Entity(entity.ClrType).HasKey(orderedKeys);
}

我没有在所有情况下都对此进行全面测试,但它适用于我的基本测试。希望这可以帮助某人

于 2019-05-14T17:40:27.363 回答
7

通过配置,您可以这样做:

Model1
{
    int fk_one,
    int fk_two
}

Model2
{
    int pk_one,
    int pk_two,
}

然后在上下文配置中

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Model1>()
            .HasRequired(e => e.Model2)
            .WithMany(e => e.Model1s)
            .HasForeignKey(e => new { e.fk_one, e.fk_two })
            .WillCascadeOnDelete(false);
    }
}
于 2014-07-18T03:47:38.507 回答