首先使用EF代码映射复合键

loy*_*low 102 c# sql-server entity-framework entity-framework-6

Sql server表:

SomeId PK varchar(50) not null 
OtherId PK int not null
Run Code Online (Sandbox Code Playgroud)

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

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

    [Key]
    public int OtherId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

这个地方有官方文件吗?

Iro*_*n84 168

你肯定需要输入列顺序,否则SQL Server应该如何知道哪一个先行?以下是您需要在代码中执行的操作:

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

  [Key, Column(Order = 1)]
  public int OtherId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你也可以看看这个问题.如果您需要官方文档,我建议您查看官方EF网站.希望这可以帮助.

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

  • `否则,SQL Server应该如何知道哪一个首先出现?` - 为什么不知道每个其他列的顺序相同? (28认同)
  • EF 不知道其他列的顺序,您可以按任何顺序插入列,只要指定名称即可。如果 EF 需要复合 PK 的顺序,则它必须与索引相关。 (2认同)

Kri*_*hna 36

对于使用Entity框架映射Composite主键,我们可以使用两种方法.

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;}
}
Run Code Online (Sandbox Code Playgroud)

我的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});
    }
}
Run Code Online (Sandbox Code Playgroud)

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;}
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅以下链接.

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

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

  • FYI for EF Core,选项2是[不可能](https://docs.microsoft.com/zh-cn/ef/core/modeling/keys#fluent-api),“只能使用流利的API-约定永远不会设置组合键,并且您不能使用数据注释来配置组合键。” (4认同)
  • 复合主键只能使用“OnModelCreating”中的“HasKey”设置。 (2认同)

viv*_*una 16

您可以PrimaryKey在 EF7 中使用属性。[PrimaryKey] 属性是在 EF Core 7.0 中引入的。在旧版本中使用 Fluent API。

例子

[PrimaryKey(nameof(State), nameof(LicensePlate))]
internal class Car
{
    public string State { get; set; }
    public string LicensePlate { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

参考:https://learn.microsoft.com/en-us/ef/core/modeling/keys? tabs=data-annotations


phi*_*n5d 7

通过Configuration,您可以执行以下操作:

Model1
{
    int fk_one,
    int fk_two
}

Model2
{
    int pk_one,
    int pk_two,
}
Run Code Online (Sandbox Code Playgroud)

然后在上下文配置中

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我以为我会补充这个问题,因为它是排名靠前的Google搜索结果。

如注释中所指出的那样,在EF Core中,不支持使用注释(键属性),并且必须流畅地完成注释。

当我在进行从EF6到EF Core的大型迁移时,这并不好用,因此我尝试通过使用Reflection查找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);
}
Run Code Online (Sandbox Code Playgroud)

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