Настройка внешнего ключа «один ко многим» для свойства, отличного от первичного ключа

#c# #asp.net #entity-framework #asp.net-core #entity-framework-core

#c# #asp.net #entity-framework #asp.net-core #entity-framework-core

Вопрос:

Возможно, это простой вопрос, но мне не удалось разобраться в нем после нескольких часов чтения документации Microsoft. В моей БД есть следующие 2 модели (я упростил их для лучшего понимания):

 public class Schedule
{
    public int Id { get; set; }
    ...
    public string Role { get; set; }
}

public class Roles
{
    public int Id { get; set; }
    ...
    public string RoleDisplay { get; set; }
}
 

Мне нужно настроить Role строку из Schedule модели как внешний ключ с отношением «один ко многим» к RoleDisplay ключу в Roles модели. Таким образом, у Schedule нас может быть много записей с Role ячейкой, указывающей на Roles таблицу.

Если бы это был обычный идентификационный ключ, я бы добавил

 public Roles Roles { get; set; }
 

to Schedule и EF автоматически сгенерируют соответствующий RoleID столбец в Schedule таблице.

Проблема в том, что я не имею дело с первичным ключом, и соглашение об именовании ключей не соответствует стандарту

 <TableName><ColumnName> 
 

Я слышал, что это можно настроить в Fluent API, что-то вроде:

 modelBuilder.Entity<Schedule>()
    .HasOne()
    .WithMany()
    .HasForeignKey();
 

но я не понял, что нужно заключить в скобки для каждого оператора.

Не могли бы вы мне помочь?

Комментарии:

1. Добавлен ответ. Посмотрите, это решит вашу проблему.

2. @atiyar извините, был занят тестированием других вещей. Это именно то, что я искал, спасибо!

Ответ №1:

Поскольку у вас нет никакого свойства навигации ни для одного объекта, вы должны использовать общую версию HasOne<Roles>() , чтобы указать, на какую таблицу ссылается внешний ключ. Как только это станет понятным для EF, вам не нужно ничего передавать WithMany() . Попробуйте выполнить следующее —

  1. Объявить RoleDisplay как альтернативный ключ на Roles
 modelBuilder.Entity<Roles>(e =>
{
    e.HasKey(p => p.Id);
    e.HasAlternateKey(p => p.RoleDisplay);
});
 
  1. При настройке внешнего ключа Schedule укажите, на какой ключ Roles он должен быть нацелен —
 modelBuilder.Entity<Schedule>(e =>
{
    e.HasKey(p => p.Id);
});
modelBuilder.Entity<Schedule>()
    .HasOne<Roles>()
    .WithMany()
    .HasForeignKey(p => p.Role)
    .HasPrincipalKey(p => p.RoleDisplay);
 

Надеюсь, это поможет.

Ответ №2:

Это будет работать. Это довольно просто. Я все еще не понимаю, чего вы не поняли?

 public class Schedule
{
    public int Id { get; set; }
    public Role Role { get; set; }
}

public class Role
{
    public int Id { get; set; }
    public string RoleDisplay { get; set; }
    public ICollection<Schedule> Schedules { get; set; }

}