Entity Framework Core - эффективное хранение / запрос многоязычных записей в базе данных - PullRequest
0 голосов
/ 03 июня 2019

Я создаю приложение, которое должно поддерживать более одного языка.

Поэтому некоторые записи в моей базе данных должны иметь несколько версий для каждого языка.

Сначала я объясню, как я в настоящее время достигаю этого: рассмотрим объект с именем Region, который представляет географическое местоположение и просто имеет имя.

Я бы спроектировал свои сущности так:

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

    public List<RegionLanguage> Languages { get;set; }
}

public class RegionLanguage 
{
    public Region Region { get;set; } // Parent record this language applies to
    public string CultureCode { get; set; } // Will store culture code such as en-US or fr-CA

    // This column/property will be in the language specified by Culturecode
    [StringLength(255)]
    public string Name { get;set; }
}

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

Используя вышеуказанную структуру, я могу запросить Region и сгенерировать модель представления на основе конкретной информации о культуре:

var region = _context.Regions.Where(e => e.Id == 34)
                     .Include(e => e.Languages)
                     .FirstOrDefault();

var viewModel = new RegionViewModel 
                    {
                         Name = region.Languages.FirstOrDefault(e => e.CultureCode == "en-US")?.Name // en-US would be dynamic based on the user's current language preference
                    }

Вы можете видеть, что это становится неэффективным, поскольку мне приходится включать ВСЕ языковые записи для объекта, который я извлекаю, когда мне фактически нужен только один, и затем искать правильный язык в памяти. Конечно, это становится еще хуже, когда мне нужно получить список Regions, который затем должен вернуть большое количество ненужных данных.

Конечно, это возможно, используя SQL напрямую, просто добавив дополнительное предложение в оператор join:

select * 
from Regions 
left join RegionLanguage on (RegionLanguage.Region = Regions.Id and RegionLanguage.CultureCode = 'en-US')

Однако, насколько я понимаю, это невозможно сделать из Entity Framework Core без использования RawQuery ( EF: включите с предложением where )

Так что возникает вопрос: есть ли лучший способ получения многоязычных записей в базе данных с помощью EF Core? Или я должен просто продолжить свой подход и надеяться, что EF Core реализует Include фильтрацию к тому моменту, когда мое приложение действительно нуждается в этом (я признаю, что, возможно, я немного преждевременно оптимизирую, но мне искренне любопытно, если есть лучший способ чтобы достичь этого).

Ответы [ 2 ]

0 голосов
/ 03 июня 2019

Вы можете использовать Глобальный фильтр запросов

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<RegionLanguage>(builder =>
    {
        builder.HasQueryFilter(rl => rl.CultureCode == "en-US");
    });
}
0 голосов
/ 03 июня 2019

Вы можете использовать проекцию.

var languageRegion = await _context.Regions
.Select(p => new Region
{
     Languages = p.Languages.FirstOrDefault(e => e.CultureCode == "en-US")
}.FirstOrDefaultAsync(e => e.Id == 34);

Если регионы и языки не меняются часто, вы можете использовать кэширование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...