2016-04-21 5 views
0

У меня есть одна проблема.Entity Framework Linq для сопоставления объектов

Database Шма

================== 
|parts   | 
================== 
| partId |textId | 
================== 

======================== 
texts     | 
======================== 
|TextId|LanguageId|text| 
======================== 

============================ 
languages     | 
============================ 
|LanguageId|LanguageIsoCode| 
============================ 

Я хочу, чтобы отобразить этот результат к следующему объекту

public long PartId { get; set; } 
public Dictionary<string,string> Name { get; set; } 

например.

{ 
    PartId: 32020 
    Name: {["en": "Blah", "es": "Blah2"]} 
} 

это то, что я пробовал, но Im работает в TimeOut с этим запросом.

var query = (from p in _context.epc_parts 
     select new //select first dynamic object 
     { 
      PartId = p.PartID, 
      Code = p.PartName, 
      Name = (from trans in _context.epc_texts 
        join lang in _context.epc_languages on trans.LanguageID equals lang.LanguageID 
        where p.TextID == trans.TextID 
        select new 
        { 
         LanguageId = lang.shortname.ToLower(), 
         Caption = trans.Caption 
        }) 

     }).AsEnumerable().Select(x => new SearchPartModel //transform it here when we can use dictionary 
     { 
      Code = x.Code, 
      PartId = x.PartId, 
      Name = x.Name.ToDictionary(t => t.LanguageId, t => t.Caption) 
     }); 

Таблица деталей содержит около 60 тыс. Строк для каждой строки, имеется 7 переводов. Свойства навигации не могут использоваться, потому что Shema не использует внешние ключи, а модель создается из db.

+0

Почему вы используете 'AsEnumerable()' вместо 'ToList()' Я считаю, что если вы делаете ToList, он выполнит запрос, и преобразование будет выполняться в памяти. Поправьте меня если я ошибаюсь. Также попробуйте использовать 'NavigationProperty' вместо соединения – Eldho

+0

Сколько записей вы ожидаете? – Eldho

+1

Ну нет фильтра/условия, поэтому вы в основном загружаете всю схему, которую вы представили. Если это веб-страница и есть много данных, тайм-аут не является неожиданным. –

ответ

0
from p in _context.epc_parts 
join trans in _context.epc_texts on p.TextID equals trans.TextID 
join lang in _context.epc_languages on trans.LanguageID equals lang.LanguageID 

select new { 
      PartId = p.PartID, 
      Code = p.PartName, 
      Name = new 
       { 
        LanguageId = lang.shortname.ToLower(), 
        Caption = trans.Caption 
       } 

} 

Это должно быть лучше, в противном случае в текущей реализации для каждого part вы запрашивая texts таблицу

+0

С этим запросом я не получу словарь для переводов, поскольку я не хочу. Как получить словарь всех переводов в одном объекте, как описано в вопросе. –

+0

да, но вы можете сделать то же самое, что делаете, чтобы преобразовать его в словарь, я думал, что главной проблемой была проблема с тайм-аутом –

1

я решил его с этим запросом. Для всего запроса потребовалось около 20 секунд для загрузки всего, что подходит для этой цели. Сначала я использую группу.

(from p in _context.epc_parts 
        join trans in _context.epc_texts on p.TextID equals trans.TextID 
        join lang in _context.epc_languages on trans.LanguageID equals lang.LanguageID 
        select new 
        { 
         PartId = p.PartID, 
         Code = p.PartName, 
         Caption = trans.Caption, 
         LanguageId = lang.shortname.ToLower() 
        }).AsEnumerable().GroupBy(x => x.PartId).Select(g => new SearchPartModel 
        { 
         Code = g.Select(x => x.Code).FirstOrDefault(), 
         PartId = g.Key, 
         Name = g.Select(x => new 
         { 
          x.LanguageId, 
          x.Caption 
         }).Distinct().ToDictionary(y => y.LanguageId, y => y.Caption) 
        });