Я переношу свое php-приложение в ядро .net с помощью Entity Framework Core.

С некоторыми из моих моделей связаны переводы из таблицы translations. Способ связывания моделей с переводами осуществляется с помощью modelname и modelid. modelname - это имя класса, а id - это идентификатор этого объекта. Имейте в виду, что объект может иметь несколько переводов с уникальным слагом.
Мне было интересно, если это можно легко реализовать с помощью структуры лица. Таким образом, модели связаны по своему идентификатору, но также фильтруются по собственному имени класса. Придется ли мне создавать это отношение в свободном API для каждой модели или есть лучшее решение для этого?

Ниже приведен небольшой пример того, как выглядит база данных. Но в реальной базе данных есть еще много таблиц с переводами. База данных, конечно, может быть изменена при необходимости.

enter image description here

1
Jerodev 8 Сен 2017 в 11:28

3 ответа

Лучший ответ

Решением, которое я использовал для решения этой проблемы, является добавление новой таблицы Translatables. каждая переводимая таблица теперь имеет поле translatable_id, и все переводы связаны с Translatable.

-2
Jerodev 15 Сен 2017 в 08:34

Кажется, вы хотите добиться полиморфной ассоциации со стратегией TPC.

К сожалению, текущая версия EF Core 2.0 не поддерживает TPC, и планируется выпустить эту функцию в EF Core 2.1 - https://github.com/aspnet/EntityFrameworkCore/wiki/Roadmap

Это решение, которое работает с EF 6.0:

public class Context : DbContext
{

    public Context() : base()
    {

    }

    public IDbSet<Translation> Translations { get; set; }

    public IDbSet<TranslatedModel> TranslationModels { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Store>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("Stores");
            });

        modelBuilder.Entity<Publisher>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("Publishers");
            });

        modelBuilder.Entity<Translation>()
            .HasRequired(t => t.TranslatedModel)
            .WithRequiredDependent(t => t.Translation);
    }
}

public class Translation
{
    public int Id { get; set; }

    public string Value { get; set; }

    public TranslatedModel TranslatedModel { get; set; }
}

public abstract class TranslatedModel
{
    public int Id { get; set; }

    public Translation Translation { get; set; }
}

public class Store : TranslatedModel
{
    public int Website { get; set; }

}

public class Publisher : TranslatedModel
{
    public string Website { get; set; }
}

Проблема здесь в том, что у вас могут быть одинаковые идентификаторы для продуктов и магазинов, что приводит к конфликтам. Поэтому я бы рекомендовал вместо указания идентификатора модели и идентификатора модели в качестве ссылочного ключа, просто измените тип идентификатора с int на GUID и удалите имя модели.

Больше информации здесь:

https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines

0
Jan Muncinsky 8 Сен 2017 в 17:04

То, что я знаю, что EF DOES предлагает, что могло бы помочь, - то, что EF предлагает полиморфизм, основанный на условиях. Вы можете реализовать класс Model, используя «Translations» в качестве основы таблицы, сделать так, чтобы Products / Store / Publishers наследовали от Model, и определить условие, при котором создается экземпляр Product / Store / Publisher, исходя из поля «имя_модели».

Я не совсем уверен, но в дочерних классах вы можете определить эти свойства навигатора как относящиеся только к одному типу.

Вот руководство:

https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application

0
Kevin Hirst 8 Сен 2017 в 12:48