Проблема с EF core и LINQ
У меня в БД есть таблица "FormFields", в которой есть связь с таблицей "Fileds" по полю "IdField". В обоих таблицах так же есть поле "name".
в приложении я хочу реализовать функционал, в котором если поле "FormFields.name" == null то возвращается поле "Fileds.Name"
для этого я настроил связи в EF между сущностями и выбрал из БД необходимые таблицы со связями:
modelBuilder.Entity<FormField>(entity =>
{
entity.ToTable("formfield", "web");
entity.Property(e => e.Id).HasColumnName("id").UseIdentityAlwaysColumn();
entity.Property(e => e.IdForm).HasColumnName("idform");
entity.Property(e => e.IdField).HasColumnName("idfield");
entity.Property(e => e.Name).HasColumnName("name");
entity.Property(e => e.ShortName).HasColumnName("shortname");
entity.Property(e => e.Description).HasColumnName("description");
entity.Property(e => e.Active).HasColumnName("active");
entity.Property(e => e.SortPosition).HasColumnName("sortposition");
entity.HasOne(d => d.IdFormNavigation)
.WithMany(p => p.FormFields)
.HasForeignKey(d => d.IdForm)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("formfield_fk_form");
entity.HasOne(d => d.IdFieldNavigation)
.WithMany(p => p.FormFields)
.HasForeignKey(d => d.IdField)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("formfield_fk_field");
});
запрос к БД:
var context = await DbFactory.CreateDbContextAsync();
Frame = await context.Frames
.Where(f => f.Id == idframe)
.Include(f => f.Forms)
.ThenInclude(t => t.FormFields)
.ThenInclude(tf => tf.IdFieldNavigation)
.FirstOrDefaultAsync();
Дополнительно я переопределил стандартные get и set для сущности "FormFields":
public class FrameField
{
[NotMapped]
private string? _Name { get; set; } = null;
public string Name
{
get { get { return _Name ?? IdFieldNavigation.Name; } }
set { _Name = value; }
}
[Required]
public int? IdField { get; set; } = null;
public virtual Field IdFieldNavigation { get; set; }
В результате выполнения кода, описанного выше (Frame = await context.Frames...) я получаю ошибку, так как во время выполнения FrameField.IdFieldNavigation равен null", и при этом IdField имеет необходимое значение
Если оставить стандартные get set, то все работает нормально и при том же запросе в БД, я могу обратиться к IdFieldNavigation.name вручную, когда захочу.
В чем моя ошибка?
(есть ощущение, что "ThenInclude(tf => tf.IdFieldNavigation)" должно вызываться раньше, чем происходит маппинг данных из БД в сущность и запрос этих данных. Но как это сделать - не понятно)
Я изменил класс и это работает, но вопрос остается открытым:
public class FrameField
{
public string? Name { get; set; } = null;
[NotMapped]
public string NameFieldNavigation
{
get { return Name ?? IdFieldNavigation.Name; }
}