Подтвердить что ты не робот

Отображение составных клавиш с использованием кода 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; }
}

Я видел несколько примеров, где вам нужно установить порядок для каждого столбца, что требуется?

Есть ли там официальная документация?

4b9b3361

Ответ 1

Вам определенно нужно указать порядок столбцов, иначе как SQL Server должен знать, какой из них идет первым? Вот что вам нужно сделать в вашем коде:

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

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

Вы также можете посмотреть этот вопрос SO. Если вам нужна официальная документация, я бы рекомендовал посмотреть официальный веб-сайт . Надеюсь, это поможет.

EDIT: Я только что нашел сообщение в блоге от Джули Лерман со ссылками на все виды доброты EF 6. Вы можете найти все, что вам нужно здесь.

Ответ 2

Для сопоставления первичного ключа Composite с использованием инфраструктуры Entity мы можем использовать два подхода.

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

Код в моем DBC-тексте будет выглядеть следующим образом:

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?

Ответ 3

Через конфигурацию вы можете сделать это:

Model1
{
    int fk_one,
    int fk_two
}

Model2
{
    int pk_one,
    int pk_two,
}

то в контексте 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);
    }
}

Ответ 4

Я думал, что добавлю к этому вопросу, так как это лучший результат поиска Google.

Как было отмечено в комментариях, в EF Core нет поддержки для использования аннотаций (атрибут Key), и это должно быть сделано с помощью свободно.

Поскольку я работал над большой миграцией с 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);
}

Я не полностью проверял это во всех ситуациях, но это работает в моих основных тестах. Надеюсь, это поможет кому-то