Я использую EF 4.1 и пытаюсь перечислить список компаний для сетки. У меня есть два варианта в текущем проекте: выбрать все компании из DbContext (Entities
) и загрузить их в объект неанонимного типа (скажем, EmpresaGrid
) или выделить все компании в объекты анонимного типа с одинаковыми структура типа Empresa
(из которой я выбираю сущность).
Первый вариант (создание класса модели для этого) потребует немного больше работы, но в конечном итоге может стать более читабельным. Тем не менее, я не уверен в этом. Второй вариант - это то, что я использую прямо сейчас.
Итак, первый вопрос : лучше создать класс модели только для отображения данных или использовать анонимный тип? О прямом выборе не может быть и речи: SELECT *
слишком велик, и это может сделать все чертовски медленным (я полагаю). Поэтому выбор в другой тип создает пользовательский запрос только с необходимыми полями.
Используя второй вариант (анонимный тип), у меня есть этот код (упрощенная версия):
public static IEnumerable<object> Grid()
{
Entities db = new Entities();
var empresas = db.Empresas
.Select(e => new
{
Cgc = e.Cgc, // PK
(...)
Address = new
{
AddressLine = e.EnderecoSede.AddressLine,
(...)
}
},
Contato = e.Contato,
(...)
})
.ToList();
return empresas;
}
Анонимный тип, который я создаю, содержит около 40 строк кода, поэтому он довольно большой, но он воссоздает часть структуры класса Empresa
(поскольку сетка ожидает объект Empresa
). Во всяком случае, у меня проблема с форматом данных. Например, я хотел бы отформатировать свойство Cgc
, используя пользовательский формат строки. У меня есть публичный метод для этого, FormataCgc
. Этот метод получает строку и возвращает ее в формате, используя некоторые внутренние условия.
Итак, моя проблема в том, как это сделать. Например, я пробовал это:
var empresas = db.Empresas
.Select(e => new
{
Cgc = FormataCgc(e.Cgc),
}
Но это не работает, потому что FormataCgc не может быть переведен в SQL (и я не хочу его преобразовывать). Я также попробовал это:
var empresas = db.Empresas
.Select(e => new
{
(...)
}
.ToList();
foreach (var e in empresas) {
e.Cgc = FormataCgc(e.Cgc);
}
Но это невозможно сделать, поскольку анонимные типы имеют только свойства только для чтения.
Итак, мой второй вопрос : как именно я могу это сделать? Мне нужно изменить данные после выбора, но с использованием анонимных типов? Я провел небольшое исследование, и лучшее, что я нашел, было следующее: Вызов пользовательского метода в запросе LINQ . В этом решении Ладислав предложил сделать второй выбор из IEnumerable, но, поскольку сетка исключает Empresa
, я не могу этого сделать (мне нужно изменить или добавить свойства, а не инкапсулировать их).
Я не уверен, был ли я достаточно ясен, но не стесняйтесь задавать любые вопросы. Кроме того, сеткой, которую я сейчас использую, является Telerik ASP.NET MVC Grid, которая получает IEnumerable (где T - класс) в качестве данных модели и выполняет итерацию каждого объекта, выполняя свою магию.