web-dev-qa-db-ja.com

最初にEFコードを使用して複合キーをマッピングする

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; }
}

各列の順序を設定する必要があるいくつかの例を見てきましたが、それは必須ですか?

これに関する公式文書はどこかにありますか?

98
loyalflow

間違いなく列の順序を設定する必要があります。そうでない場合、SQL Serverはどの列が最初に行くかをどのように判断するのでしょうかコードで行う必要があることは次のとおりです。

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

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

this SO question もご覧ください。公式のドキュメントが必要な場合は、 EF公式Webサイト をご覧になることをお勧めします。お役に立てれば。

編集:ジュリーラーマンのブログ投稿で、あらゆる種類のEF 6の良さへのリンクを見つけました。必要なものは何でも見つけることができます here

160
IronMan84

Entityフレームワークを使用してComposite主キーをマッピングするには、2つのアプローチを使用できます。

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を使用して複合一意キーを追加する方法

31
Krishna

設定により、これを行うことができます。

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);
    }
}
7
philn5d

これはトップのGoogle検索結果なので、この質問に追加すると思いました。

コメントで指摘されているように、EF Coreでは注釈(キー属性)の使用はサポートされておらず、流withに実行する必要があります。

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

これをすべての状況で完全にテストしたわけではありませんが、基本的なテストでは機能します。これが誰かを助けることを願っています

3
cmorgan091