2017-02-17 2 views
0

я следующие классы домена в моей модели автоматически генерируется из моей базы данных:Как преобразовать дочернюю коллекцию объектов домена в коллекцию пользовательских объектов с использованием Entity Framework и ASP.NET Web API (Visual Basic)?

Public Class Person 
    Public Property id As Integer 
    Public Property lastName As String 
    Public Property addresses As ICollection(Of Address) = New HashSet(Of Address)() 
End Class 

Public Class Address 
    Public Property id As Integer 
    Public Property personId As Integer 
    Public Property addressLine As String 
End Class 

И я создал следующие пользовательские классы DTO для представления данных, передаваемых на пользователя:

Public Class PersonDTO 
    Public Property lastName As String 
    Public Property addresses As ICollection(Of AddressDTO) = New HashSet(Of AddressDTO)() 
End Class 

Public Class AddressDTO 
    Public Property addressLine As String 
End Class 

I Я хотел бы сделать следующее, чтобы запросить базу данных и вернуть коллекцию объектов PersonDTO, каждая со своей коллекцией объектов AddressDTO:

По какой-то причине этот запрос компилирует и не выдает никаких исключений при его выполнении, но данные не возвращаются, и на самом деле мой клиент получает ошибку сервера 500 при ее запуске. Тем не менее, она работает просто отлично, если я изменить код для этого (который предоставляет объект домена, который я предпочел бы не делать):

Public Class PersonDTO 
    Public Property lastName As String 
    Public Property addresses As ICollection(Of Address) = New HashSet(Of Address)() 
End Class 

Using db as New DatabaseContext() 

    Dim people As IQueryable(Of PersonDTO) = 
     db.Persons.Include("addresses") 
     .Select(Function(p) New PersonDTO With 
     { 
      .lastName = p.lastName, 
      .addresses = p.addresses 
     }) 

End Using 

Спасибо заранее за вашу помощь!

+0

Не имеет значения, когда вы заканчиваете утверждение с помощью .ToList()? –

+0

это поможет, если вы сообщите нам об ошибке – BennyM

+0

Ошибка при отладке, она очень легко выполняет запрос. Проблема в том, что он не возвращает никаких данных, и веб-API генерирует 500-HTTP-ответный код. Одна вещь, которую я заметил во время отладки, заключается в том, что при переходе через код объект IQueryable «исчезает» после того, как он попадает в этот внутренний выбор по адресу DTO. Под этим я подразумеваю, что до этого я могу читать свойства объекта в отладчике, но как только он попадает во внутренний выбор, внезапно отладчик говорит, что он либо не объявлен, либо у меня нет доступа к его свойствам. Очень странно ... – Erik

ответ

0

После долгого копания, я был в состоянии найти ответ здесь:

LINQ to Entities projection of nested list

Я должен был спроектировать вложенную коллекцию DTOS как свойство анонимного класса. Таким образом, он может сохранить его как IQueryable, а не актуализировать его как список. Затем я мог бы вызвать ToListAsync для запроса базы данных за один раз, а затем использовать LINQ для объектов, чтобы поместить коллекцию AddressDTO в PersonDTO. Для меня работал следующий код:

Using db as New DatabaseContext() 

    Dim anonymousPersonDTOList = 
     db.Persons.Include("addresses") 
     .Select(Function(p) New With 
      { 
       .pDTO = New PersonDTO With 
        { 
         .lastName = p.lastName 
        }, 
       .addresses = p.addresses.Select(Function(a) New AddressDTO With 
        { 
         .addressLine = a.addressLine 
        }) 
      }).ToListAsync() 

    Dim personDTOList as IEnumerable(Of PersonDTO) = 
     anonymousPersonDTOList.Select(
      Function(p) 
       p.pDTO.addresses = p.addresses.ToList() 
       Return p.pDTO 
      End Function) 

    Return personDTOList 

End Using 
Смежные вопросы