EF核心:使用链接属性为组合PK的一部分定义外键

时间:2019-04-25 15:52:01

标签: c# entity-framework-core entity-framework-core-2.2

我有以下模型:

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,由({InstanceIdDatabaseNameSchemaName)组成。

我想定义一个从schema.InstanceIdinstance.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 :(得分:0)

可以使用以下语法完成此操作:

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