Как объединить 2 объекта, чтобы получить переведенный текст в Entity Framework 6

#c# #entity-framework #entity-framework-6

#c# #entity-framework #entity-framework-6

Вопрос:

Я использую EF 6 Code-First и хочу, чтобы мои клиенты вводили новые записи на нескольких языках. Чтобы сохранить это, я сохраняю все тексты в словарном объекте с пользовательским ключом и ссылаюсь на него из другого моего объекта через этот ключ.

Это базовый образец моих сущностей:

   Dictionary
    ID  Key          IsoCode    Value
    1   firstEntry   en-US      My new entry
    2   secondEntry  en-US      My second entry
    3   firstEntry   es-ES      Mi nueva entrada

  Entries    
    ID   Name         CreationDate
    1    firstEntry   2020-11-04
    2    secondEntry  2020-11-07
  

Чего я хочу добиться, так это запросить объект Entries с кодом ISO и получить новый объект, в котором поле Name заменяется полем Value из объекта Dictionary.

Это то, что у меня есть прямо сейчас:

 public List<Entry> GetEntries(string isoCode)
{    
    var query = (from e in dbContext.Entry
                 join d in dbContext.Dictionary on e.Name equals d.Key
                 where d.IsoCode == isoCode
                 select new
                 {
                    entry= e,
                    Text = d.Value
                 }).ToList();

    return query.Select(t => new Entry
      {
         Id = t.entry.Id,
         Name = t.Text,
         CreationDate = t.CreationDate
      }).ToList();
}
  

Есть ли лучший способ сделать это без создания двух списков?
Является ли этот подход с использованием ключа для получения переведенного текста лучшей практикой или я здесь упускаю суть?

Комментарии:

1. В вашем подходе нет ничего плохого, хотя при глобализации вам следует подумать об использовании файла resx, который подходит для большинства подходов. О вашем запросе, если вы хотите сделать его «однострочным», вы можете удалить запрос. Выберите и добавьте код после выбора нового ({}) и возвращайте без создания переменной

Ответ №1:

Вот рабочий пример вашего кода, использующего 2 списка вместо ваших таблиц (конечно).

Вы можете просто создать запись в первом запросе. Вам не нужно .ToList() в этой процедуре. Просто верните IEnumerable .

 using System;
using System.Collections.Generic;
using System.Linq;

namespace JoinEntities
{
    class Program
    {
        static List<Dict> dictionary = new List<Dict>
        {
            new Dict
            {
                ID = 1,
                Key = "firstEntry",
                IsoCode = "en-US",
                Value = "My new entry"
            },
            new Dict
            {
                ID = 2,
                Key = "secondEntry",
                IsoCode = "en-US",
                Value = "My second entry"
            },
            new Dict
            {
                ID = 3,
                Key = "firstEntry",
                IsoCode = "es-ES",
                Value = "Mi nueva entrada"
            },
        };

        static List<Entry> entries = new List<Entry>
        {
            new Entry
            {
                Id = 1,
                Name = "firstEntry",
                CreationDate = new DateTime(2020, 11, 04)
            },
            new Entry
            {
                Id = 1,
                Name = "secondEntry",
                CreationDate = new DateTime(2020, 11, 07)
            }
        };


        static void Main(string[] args)
        {
            var list = GetEntries("en-US");
        }

        public static IEnumerable<Entry> GetEntries(string isoCode)
        {
            return from e in entries
                   join d in dictionary on e.Name equals d.Key
                   where d.IsoCode == isoCode
                   select new Entry
                   {
                       Id = e.Id,
                       Name = d.Value,
                       CreationDate = e.CreationDate
                   };
        }
    }

    internal class Dict
    {
        public int ID { get; set; }
        public string Key { get; set; }
        public string IsoCode { get; set; }
        public string Value { get; set; }
    }

    internal class Entry
    {
        public object Id { get; set; }
        public object Name { get; set; }
        public object CreationDate { get; set; }
    }
}
  

Комментарии:

1. Насколько я знаю, вы не можете этого сделать, используя объекты. Вот почему я использую второй запрос.

2. Вы даже пробовали мое решение?