Подтвердить что ты не робот

Сопоставьте два разных объекта с одной таблицей?

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

Что я хотел бы сделать, это добавить в Entity вручную, а затем просто сопоставить его с исходной таблицей, но удалите столбцы, которые мне не нужны. Я все это установил, но я получаю довольно очевидную ошибку:

Проблема при отображении фрагментов... EntitySets 'FmvHistoryTrimmed' и "FMVHistories" оба отображаются на таблица "FMVHistory". Их первичные ключи может столкнуться.

Есть ли другой способ, которым я должен это делать? Опять же, большую часть времени используются все столбцы, поэтому я не хочу обрезать исходный объект и помещать "дополнительные" поля в сложный тип.

4b9b3361

Ответ 1

Вы не можете сопоставить два обычных объекта в одной таблице. У вас есть несколько вариантов:

  • Использовать разбиение таблиц.
  • Использовать пользовательский запрос с проекцией на тип не-сущности (как предлагалось @Aducci)
  • Использовать QueryView
  • Использовать представление базы данных или непосредственно DefiningQuery

Разделение таблиц

Разделение таблиц позволяет сопоставить таблицу с двумя объектами в соотношении 1:1. Первый объект будет содержать только PK и подмножество полей, которые вам всегда нужны. Второй объект будет содержать все остальные поля и PK. Оба объекта будут содержать свойство навигации друг к другу. Теперь, если вам нужно только подмножество полей, вы будете запрашивать первый объект. Если вам нужны все поля, вы будете запрашивать первый объект и включать свойство навигации для второго объекта. Вы также можете использовать ленивую загрузку второго объекта, если вам это нужно.

QueryView

QueryView - это запрос ESQL, определенный непосредственно в вашем сопоставлении (MSL), и он сопоставляется новому типу сущности readonly. Вы можете использовать QueryView для определения проекции вашей полной сущности на сущность. QueryView должен быть определен вручную в EDMX (он недоступен в дизайнере). Поскольку я знаю, что QueryView сначала не доступен в коде, но на самом деле он аналогичен произвольной проекции на тип не-сущности.

DefiningQuery

DefiningQuery - это настраиваемый запрос, определенный непосредственно в вашей модели хранения (SSDL). DefiningQuery обычно используется при сопоставлении с представлениями в базе данных, но вы можете использовать его для любого пользовательского SQL SELECT. Вы будете отображать результат запроса на тип данных только для чтения. DefiningQuery должен быть определен вручную в EDMX (он недоступен в дизайнере). Он также напрямую не доступен в коде, но на самом деле это то же самое, что и вызов SqlQuery на DbDatabase. Проблема с DefiningQuery заключается в том, что после того, как вы вручную определяете ее в SSDL, вы не можете использовать модель обновления из базы данных, потому что эта операция заменяет полный SSDL и удаляет определение вашего запроса.

Ответ 2

Я бы создал представление в базе данных, содержащее только данные, которые вам нужны, и добавьте представление в вашу модель данных сущности.

Если вы не хотите изменять базу данных, вы можете создать Linq для сущностей или инструкцию ESQL, проецируемую в класс POCO, только с необходимой информацией.

public IQueryable<SimpleObject> GetView(DBContext context)
{
    return  (from obj in context.ComplexObjects
            select new SimpleObject() { Property1 = obj.Property1,
                                        Property1 = obj.Property2
                                      }); 
}