EF Core: определение внешнего ключа для части составного ПК с использованием связанного свойства - PullRequest
2 голосов
/ 25 апреля 2019

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

internal class SchemaEfEntity
{
    [Required]
    [MaxLength(128)]
    public string Name { get; set; }

    [Required]
    public DatabaseEfEntity Database { get; set; }
}

internal class DatabaseEfEntity
{
    [Required]
    public string Name { get; set; }

    [Required]
    public InstanceEfEntity Instance { get; set; }

    public ICollection<SchemaEfEntity> Schemas { get; set; }
}

internal class InstanceEfEntity : IEfIdEntity
{
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    public ICollection<DatabaseEfEntity> Databases { get; set; }
}

public sealed class MyDbContext : DbContext
{
        internal DbSet<InstanceEfEntity> Instances { get; set; }
        internal DbSet<DatabaseEfEntity> Databases { get; set; }
        internal DbSet<SchemaEfEntity> Schemas { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<InstanceEfEntity>().HasKey(x => x.Id);
            modelBuilder.Entity<InstanceEfEntity>().HasIndex(x => x.Name).IsUnique();

            modelBuilder.Entity<DatabaseEfEntity>().HasKey(
                $"{nameof(DatabaseEfEntity.Instance)}{nameof(InstanceEfEntity.Id)}",
                $"{nameof(DatabaseEfEntity.Name)}");

            modelBuilder.Entity<SchemaEfEntity>().HasKey(
                $"{nameof(SchemaEfEntity.Database)}{nameof(DatabaseEfEntity.Instance)}{nameof(InstanceEfEntity.Id)}",
                $"{nameof(SchemaEfEntity.Database)}{nameof(DatabaseEfEntity.Name)}",
                $"{nameof(SchemaEfEntity.Name)}");
        }
}

Для SchemaEfEntity определен составной PK, состоящий из (InstanceId, DatabaseName и SchemaName).

Я хотел бы определить внешний ключ от schema.InstanceId до instance.Id.Я пробовал это:

        modelBuilder.Entity<SchemaEfEntity>()
            .HasOne(c => c.Database.Instance)
            .WithMany()
            .HasForeignKey(
                $"{nameof(SchemaEfEntity.Database)}{nameof(DatabaseEfEntity.Instance)}{nameof(InstanceEfEntity.Id)}"
            );

Но при создании миграции появляется следующая ошибка:

Выражение 'c => c.Database.Instance' недопустимовыражение свойства.Выражение должно представлять простой доступ к свойству: 't => t.MyProperty'.Имя параметра: propertyAccessExpression

Есть идеи?Это вообще возможно?Есть ли способ указать это «вручную», то есть не использовать цепочку свойств, а просто указать таблицу и столбец в виде простого текста?

1 Ответ

0 голосов
/ 11 мая 2019

Это можно сделать с помощью следующего синтаксиса:

modelBuilder.Entity<SchemaEfEntity>()
    .HasOne(typeof(InstanceEfEntity))
    .WithMany()
    .HasForeignKey(
        $"{nameof(SchemaEfEntity.Database)}{nameof(DatabaseEfEntity.Instance)}{nameof(InstanceEfEntity.Id)}")
    .OnDelete(DeleteBehavior.Restrict);
...