Ef Core 2.2 и внешний ключ для строго типизированного свойства ID - PullRequest
0 голосов
/ 15 января 2019

Я хотел бы создать one-to-many отношения между двумя сущностями. Предположения довольно просты, я хочу иметь коллекции сообщений об объекте Blog и Post с идентификатором блога.

public class Blog
{
    public int Id { get; private set;}
    public virtual ICollection<Post> Posts { get; private set; }
    public Blog(BlogId id) {
        Id = id.Id;
    }
}

public class Post
{
    public int Id { get; private set;}
    public virtual BlogId BlogId { get; private set; }
}

public class BlogId: IComparable<int>
{
    public int Id { get; private set; }
    public BlogId(int id)
    {
       Id = id;
    }

    public static implicit operator int(BlogId id) => id.Id;
    public static implicit operator BlogId(int id) => new BlogId(id);
    public int CompareTo(int other) => Id.CompareTo(other);
}

Конфигурация:

public class BlogConfiguration : IEntityTypeConfiguration<Blog>
{
    public void Configure(EntityTypeBuilder<Blog> builder)
    {
        builder.ToTable("Blogs");
        builder.HasKey("Id");
        builder.HasMany(n => n.Posts)
            .WithOne()
            .HasForeignKey(p => p.BlogId)
            .IsRequired()
            .OnDelete(DeleteBehavior.Cascade);
    }
}

public class PostConfiguration : IEntityTypeConfiguration<Post>
{
    public void Configure(EntityTypeBuilder<Post> builder)
    {
        builder.ToTable("Posts");
        builder.HasKey("Id");
        builder.Property(p => p.BlogId)
            .HasConversion(v => v.Id, v => new BlogId(v));
    }
}

К сожалению, он не работает со строго типизированными объектами Id. В этой ситуации мы получаем исключение:

Связь между 'Post' и 'Blog.Posts' со свойствами внешнего ключа {'BlogId': BlogId} не может быть нацелена на первичный ключ {'Id': int}, поскольку он несовместим. Настройте основной ключ или набор совместимых свойств внешнего ключа для этого отношения.

Я пытался решить эту проблему с помощью неявных операторов, интерфейса IComparable, собственных типов, но здесь ни одно из этих решений не работает. Он просто игнорирует преобразования типа BlogId как часть процесса создания отношений (builder.Property(p => p.BlogId).HasConversion(v => v.Id, v => new BlogId(v));).

Знаете ли вы какое-нибудь обходное или стандартное решение для такого случая? Я не хотел бы вносить изменения в домен из-за ограничений в слое постоянства.

...