LINQ to Entities: загрузка свойств навигации «один ко многим» в строго типизированных проекциях - PullRequest
3 голосов
/ 16 февраля 2011

Вот соответствующая часть моей модели:

enter image description here

А вот код из моего модельного класса:

/// <summary>
/// Retrieves a list of vans for binding with the BeachReach Snapshot
/// grid. Note: This method uses a POCO class that does not participate
/// in management by the entity context. See the DisplayVan class for more info
/// </summary>
/// <param name="setVanIDs">
/// You may limit which vans will be returned by passing a hash
/// set of their van IDs here
/// </param>
/// <returns>List of type DisplayVan - Unmanaged</returns>
public static List<DisplayVan> GetVansForSnapshot(HashSet<int> setVanIDs = null) {

    using (BeachReachDataEntities objContext = new BeachReachDataEntities()) {

        var qryVans = from v in objContext.vans
                                .Include("school")
                                .Include("location")

                      select new DisplayVan {
                          vanID = v.vanID,
                          vanName = v.vanName,
                          phone = v.phone,
                          capacity = (int)v.capacity,
                          schoolName = v.school.schoolName,
                          lastLocationName = v.location.locationName,
                          statusNote = v.statusNote,
                          isOffline = (v.isOffline == 1) ? true : false,
                          isPrayerRoom = (v.isPrayerRoom == 1) ? true : false,
                          isNotReady = (v.isNotReady == 1) ? true : false,
                          creationDate = v.creationDate,
                          modifiedDate = v.modifiedDate,
                          vanAssignments = (from va in objContext.vanAssignments
                                            from pr in objContext.pickupRequests
                                            where va.vanID == v.vanID
                                            where pr.pickupRequestID == va.pickupRequestID
                                            select va)
                      };

        if (setVanIDs != null && setVanIDs.Count > 0)
            return qryVans.Where(v => setVanIDs.Contains(v.vanID)).ToList<DisplayVan>();
        else
            return qryVans.ToList<DisplayVan>();

    }

}

// --------------------------------------------------------

Я также пробовал:

        var qryVans = from v in objContext.vans
                                .Include("school")
                                .Include("location")
                                .Include("vanAssignments")
                                .Include("vanAssignments.pickupRequest")


                      select new DisplayVan {
                          vanID = v.vanID,
                          vanName = v.vanName,
                          phone = v.phone,
                          capacity = (int)v.capacity,
                          schoolName = v.school.schoolName,
                          lastLocationName = v.location.locationName,
                          statusNote = v.statusNote,
                          isOffline = (v.isOffline == 1) ? true : false,
                          isPrayerRoom = (v.isPrayerRoom == 1) ? true : false,
                          isNotReady = (v.isNotReady == 1) ? true : false,
                          creationDate = v.creationDate,
                          modifiedDate = v.modifiedDate,
                          vanAssignments = v.vanAssignments
                      };

Игнорировать это **** свойства. Я использую базу данных MySQL, которая не поддерживает типы boolean.

Запрос должен проецироваться на DisplayVan вместо сущности van, потому что у меня есть некоторые вычисленные свойства, которые я связываю с сеткой данных.

Проблема заключается в том, что я пытаюсь получить доступ к свойству pickupRequest навигации объекта vanAssignment. Независимо от того, что я делаю, свойство pickupRequest равно null. Обратите внимание, у меня ленивая загрузка. Как я могу загрузить отношение pickupRequest vanAssignment через мой запрос выше?

Последнее замечание: свойство vanAssignments является списком типа vanAssignment. Спасибо за любую информацию, которую вы можете дать в этом вопросе.

Редактировать

Еще один вопрос. Итак, исходя из вашего примера, я хотел перейти на vanAssignment.person.firstName. Я попробовал это:

        var qryVans = (from v in objContext.vans
                       select new {
                           DisplayVan = new DisplayVan {
                               vanID = v.vanID,
                               vanName = v.vanName,
                               phone = v.phone,
                               capacity = (int)v.capacity,
                               schoolName = v.school.schoolName,
                               lastLocationName = v.location.locationName,
                               statusNote = v.statusNote,
                               isOffline = (v.isOffline == 1) ? true : false,
                               isPrayerRoom = (v.isPrayerRoom == 1) ? true : false,
                               isNotReady = (v.isNotReady == 1) ? true : false,
                               creationDate = v.creationDate,
                               modifiedDate = v.modifiedDate,
                               vanAssignments = v.vanAssignments
                           },
                           PickupRequests = v.vanAssignments.Select(va => va.pickupRequest),
                           People = v.vanAssignments.Select(va => va.pickupRequest.person)
                       }).ToList().Select(e => e.DisplayVan);

Когда я пытаюсь получить доступ к этому свойству, я получаю следующую ошибку:

enter image description here

1 Ответ

5 голосов
/ 16 февраля 2011

Это должно работать:

var qryVans = 
    (from v in objContext.vans
    select new
        {
            DisplayVan = new DisplayVan
            {
                vanID = v.vanID,
                vanName = v.vanName,
                phone = v.phone,
                capacity = (int)v.capacity,
                schoolName = v.school.schoolName,
                lastLocationName = v.location.locationName,
                statusNote = v.statusNote,
                isOffline = (v.isOffline == 1) ? true : false,
                isPrayerRoom = (v.isPrayerRoom == 1) ? true : false,
                isNotReady = (v.isNotReady == 1) ? true : false,
                creationDate = v.creationDate,
                modifiedDate = v.modifiedDate,
                vanAssignments = v.vanAssignments
            },
            PickupRequests = v.vanAssignments.Select(va => new {PickupReuqest = va.pickupRequest, Person = va.pickupRequest.Person})
        }
    ).ToList().Select(e => e.DisplayVan);

Включения игнорируются в этой конструкции, поэтому вы должны их оставить. Вы должны указать с дополнительным свойством, что вы тоже хотите pickupRequests. ToList() выполняет запрос, принимая требуемые данные, и, поскольку все требуемые pickupRequests находятся в контексте, у вас будут заполнены правильные поля EF анализирует поля, которые вы запрашиваете в вашей модели представления, и готовит SQL-оператор, который их примет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...