Samengestelde sleutels toewijzen met eerst EF-code

Sql-servertabel:

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

Hoe moet ik dit eerst in EF 6-code in kaart brengen?

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

Ik heb enkele voorbeelden gezien waarbij je de volgorde voor elke kolom moet instellen, is dat vereist?

Is hier ergens officiële documentatie over?


Antwoord 1, autoriteit 100%

Je moet zeker de kolomvolgorde invoeren, anders moet SQL Server weten welke eerst gaat? Dit is wat je zou moeten doen in je code:

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

Je kunt ook deze SO-vraagbekijken. Als je officiële documentatie wilt, raad ik je aan naar de officiële EF-websitete kijken. Ik hoop dat dit helpt.

EDIT: ik heb net een blogpost gevonden van Julie Lerman met links naar allerlei soorten EF 6-goedheid. Je kunt hier.


Antwoord 2, autoriteit 28%

Voor het toewijzen van samengestelde primaire sleutel met behulp van het Entity-framework kunnen we twee benaderingen gebruiken.

1) Door de OnModelCreating()-methode te negeren

Bijvoorbeeld: ik heb de modelklasse met de naam VehicleFeature zoals hieronder weergegeven.

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

De code in mijn DBContext zou zijn als ,

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) Op gegevensannotaties.

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

Raadpleeg de onderstaande links voor meer informatie.

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

2) Hoe toe te voegen een samengestelde unieke sleutel met EF 6 Fluent Api?


Antwoord 3, autoriteit 4%

Ik dacht dat ik iets aan deze vraag zou toevoegen omdat dit het beste Google-zoekresultaat is.

Zoals is opgemerkt in de opmerkingen, is er in EF Core geen ondersteuning voor het gebruik van annotaties (Key-attribuut) en moet het vloeiend worden gedaan.

Terwijl ik aan een grote migratie van EF6 naar EF Core werkte, was dit onsmakelijk en dus probeerde ik het te hacken door Reflection te gebruiken om naar het Key-attribuut te zoeken en het vervolgens toe te passen tijdens 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);
}

Ik heb dit niet in alle situaties volledig getest, maar het werkt in mijn basistests. Ik hoop dat dit iemand helpt


Antwoord 4, autoriteit 3%

Via Configuratie kunt u dit doen:

Model1
{
    int fk_one,
    int fk_two
}
Model2
{
    int pk_one,
    int pk_two,
}

vervolgens in de context config

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

Other episodes