Странно, если я наведу указатель мыши на переменную результата, она отобразится в виде списка POLICY_Record. Я просто делаю это в неправильном порядке?
В этом нет ничего странного. Я подозреваю, что вы немного смущены тем, что делает Линк. Linq сокращает наборы, поэтому мы разложим ваш исходный запрос:
var result = POLICY_Record
.Include(pt => pt.POLICY_Primer)
.Include(pt => pt.POLICY_Primer.LOOKUP)
.Where(pt => pt.LOOKUP.ABBREV == "XXX")
.Where(pt => pt.DATE >= startDate && pt.DATE <= endDate)
.Where(pt => pt.LOOKUP.TYPE == "Y")
.Where(pt => pt.STATUS == 1)
.Where(pt => !excludedTransTypes.Contains(pt.FK_Value))
.Where(pt => stateconfigs.Contains(pt.STATE))
.ToList();
, начиная с ..
var result = POLICY_Record
Я предполагаю, что POLICY_Record
в данном случае относится кDbSet вашей политики записи. Без Select
или SelectMany
ваше выражение Linq вернет сущности, с которых вы решили начать.
.Include(pt => pt.POLICY_Primer)
.Include(pt => pt.POLICY_Primer.LOOKUP)
Это говорит EF, что вы хотите загружать Policy_Primer и сущность Lookup этого учебника для начинающихдля каждой Policy_Record, которую он извлекает обратно. не требуется для того, чтобы иметь возможность записывать условия для этих полей или даже для проецирования вашего вывода. Это применимо только в том случае, если вы хотите вернуть сущности Policy_Record, и эти связанные сущности предварительно загружены и готовы к работе. (В отличие от отложенной загрузки по требованию, требующей дополнительных обращений к базе данных.)
.Where(pt => pt.LOOKUP.ABBREV == "XXX")
.Where(pt => pt.DATE >= startDate && pt.DATE <= endDate)
.Where(pt => pt.LOOKUP.TYPE == "Y")
.Where(pt => pt.STATUS == 1)
.Where(pt => !excludedTransTypes.Contains(pt.FK_Value))
.Where(pt => stateconfigs.Contains(pt.STATE))
Это ваши критерии. Вы говорите EF возвращать сущности Policy_Record, которые содержат данные, которые удовлетворяют всем этим условиям. Отсюда мы не основываем ни один из этих критериев на дополнительных загружаемых полями, таких как учебник для начинающих.
.ToList();
Это «выполняет» запрос и говорит EF вернуть все и все Policy_Records, которые удовлетворяют всемWhere
условия и вместе с этими записями включают каждый из их Policy_Primer и Lookup этого учебника для начинающих.
Следующий вопрос будет таким: если это не то, что вы хотите, что вы на самом деле ожидаете увидеть? Добавив:
.Where(pt => pt.POLICY_Primer.NUMBER == Num)
Это говорит EF, что вы хотите только Policy_Records, где их связанный номер праймера соответствует вашему параметру. Вы все равно получите Policy_Records, только те, которые содержат учебник для начинающих с этим номером.
Проекция: Это, вероятно, недостающий фрагмент. Вышеуказанные запросы уменьшили набор Policy_Records, теперь мы используем проекцию, чтобы сообщить EF, что мы хотим вернуть. Обычно это делается с помощью Select
. Например, если бы мы хотели использовать только праймеры политики для всех соответствующих политик, мы добавили бы:
.Select(pt => pt.POLICY_Primer)
, так что ...
var result = POLICY_Record
.Include(pt => pt.POLICY_Primer)
.Include(pt => pt.POLICY_Primer.LOOKUP)
.Where(pt => pt.LOOKUP.ABBREV == "XXX")
.Where(pt => pt.DATE >= startDate && pt.DATE <= endDate)
.Where(pt => pt.LOOKUP.TYPE == "Y")
.Where(pt => pt.STATUS == 1)
.Where(pt => !excludedTransTypes.Contains(pt.FK_Value))
.Where(pt => stateconfigs.Contains(pt.STATE))
.Select(pt => pt.POLICY_Primer)
.ToList();
Вместо списка записей политики мы получаемсписок учебников для начинающих. Мы можем добавить .Distinct()
после Select
, чтобы удалить дублирующиеся праймеры, если многие политики могут использовать один и тот же праймер.
Проекция полезна для уменьшения общего объема возвращаемых данных и выравнивания данных для отраженияпросто структура, которую мы хотим. Например, если мы отображаем список политик и соответствующих им праймеров, и нам нужны только некоторые поля, мы можем определить простую модель представления для результатов поиска и использовать Select
для их заполнения:
.Select(pt => new PolicyViewModel
{
PolicyNumber = pt.Policy_Number,
Date = pt.Date,
PrimerNumber = pt.Policy_Primer.Number,
// ...
})
При использовании Select
для проецирования, подобного этому, мы сообщаем EF точно, какие поля из каких сущностей мы хотим, и он будет составлять запрос для получения только этих деталей. Это позволяет базам данных более эффективно использовать индексы и сокращает время, память и пропускную способность, необходимые для запросов как на сервере базы данных, так и на сервере приложений. При использовании проекции таким способом вы также отрицаете необходимость использования Include
. EF автоматически присоединится к таблицам для получения запрошенных вами данных. Вы можете включать сущности, но, как правило, этого не следует делать, так как это устраняет преимущества уменьшения размера набора данных, а также может оставить вас открытыми для отложенных загрузок и других неприятностей, если вы возвращаете сущности.
Надеемся, что это даст вам некоторые идеи относительно того, что может отсутствовать в вашем сценарии, но не стесняйтесь прояснить свой вопрос или дополнить его тем, что вы ожидаете получить от запроса.