Как связать таблицу с помощью EF Core Code-First - PullRequest
1 голос
/ 11 апреля 2019

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

У меня есть следующая модель:

public class DataMapping
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    public string Model { get; set; } 
    public string Property { get; set; }
    public bool IgnoreProperty { get; set; } 

    [NotMapped] //<-- I had to add this as the migration was complaining that it did not know what the relation was
    public List<DataMappingRelation> DataMappingRelations { get; set; }

    public DateTime DateCreated { get; set; } = DateTime.UtcNow;
    public DateTime? DateModified { get; set; }
}

и модель Bridge, которая в основном создает отношениямежду двумя элементами DataMapping в одной и той же таблице:

public class DataMappingRelation
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [ForeignKey("DataMappingId")]
    public long? DataMapping1Id { get; set; }
    public DataMapping DataMapping1 { get; set; } 

    [ForeignKey("DataMappingId")]
    public long? DataMapping2Id { get; set; }
    public DataMapping DataMapping2 { get; set; }
}

Однако этот вызов не работает:

return _context.DataMappings.Where(x => x.Model == type.FullName)
            .Include(x=>x.DataMappingRelations)
            .ToList();

Он не похож на функцию Include и выдает исключение null ref.

Все, что мне в основном нужно сделать, - это для данного «DataMapping» получить все связанные элементы DataMapping на основе отношений в таблице «DataMappingRelations».

Да, я посмотрел на этот ответ но опять же, это пример двух отдельных таблиц, а не одной таблицы, соединяющей себя.

Я подозреваю, что все это сделал неправильно.Как я могу заставить это работать?Все примеры, которые я нашел, соединяют две отдельные таблицы.это соединит одну и ту же таблицу.

1 Ответ

1 голос
/ 11 апреля 2019

Это many-to-many с самим собой, но вся ваша конфигурация выглядит грязной.

Итак, во-первых, ваш класс DataMapping должен содержать два свойства навигации по списку для двух внешних ключей в DataMappingRelation следующим образом:

public class DataMapping
{
    ......

    public List<DataMappingRelation> DataMapping1Relations { get; set; }

    public List<DataMappingRelation> DataMapping2Relations { get; set; }

    .........
}

Теперь удалите атрибут [ForeignKey("DataMappingId")] из внешних ключей DataMapping1 и DataMapping2 следующим образом:

public class DataMappingRelation
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    public long? DataMapping1Id { get; set; }
    public DataMapping DataMapping1 { get; set; } 

    public long? DataMapping2Id { get; set; }
    public DataMapping DataMapping2 { get; set; }
}

Тогда конфигурация Fluent API должна быть следующей:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<DataMappingRelation>()
         .HasOne(dmr => dmr.DataMapping1)
         .WithMany(dm => dm.DataMapping1Relations)
         .HasForeignKey(dmr => dmr.DataMapping1Id)
         .OnDelete(DeleteBehavior.Restrict);

     modelBuilder.Entity<DataMappingRelation>()
         .HasOne(dmr => dmr.DataMapping2)
         .WithMany(dm => dm.DataMapping2Relations)
         .HasForeignKey(dmr => dmr.DataMapping2Id)
         .OnDelete(DeleteBehavior.Restrict);
}
...