Entity Framework linq главная проекция деталей в пользовательские классы

1

У меня есть класс Order со свойствами "ID как Int64, Description as String, Details as List (Of OrderDetail)"
Существует также класс OrderDetail со свойствами "ID как Int64, Description as String, Amount as Decimal"

Public Class Order
    Property ID As Int64
    Property Description As String
    Property Details As List(Of OrderDetail)
End Class

Public Class OrderDetail
    Property ID As Int64
    Property Description As String
    Property Amount As Decimal
End Class

Затем я создал статическую/общую функцию для вызова Entity Framework с использованием LINQ и хотел бы создать список заказов вместе с OrderDetails для каждого заказа.

Public Shared Function GetOrders() As List(Of Order)
    Dim db = New OrderEntities()

    Dim orders = (From O In db.OrderTable
    Select New Order With {
        .ID = O.OrderID,
        .Description = O.OrderDescription,
        .Details = (From OD In db.OrderDetailTable
            Where OD.OrderID = O.OrderID
            Select New OrderDetail With {
                .ID = OD.OrderDetailID,
                .Description = OD.OrderDetailDescription,
                .Amount = OD.OrderDetailAmount})
        }
    ).ToList()

    Return orders
End Function

Когда будет выполнено, я получу следующую ошибку.

Unable to cast the type 'System.Linq.IQueryable'1[[OrderDetails]]' to type 
'System.Collections.Generic.List'1[[OrderDetails]]'. 
LINQ to Entities only supports casting EDM primitive or enumeration types.



ЗАМЕТКА:
Это проблема Entity Framework, а не проблема LINQ.
Например, следующее будет работать нормально при использовании EF, но не проецируется в новый список объектов.

    Public Shared Function GetOrders() As Object
    Dim db = New OrderEntities()

    Dim orders = (From O In db.OrderTable
    Select New With {
        .ID = O.OrderID,
        .Description = O.OrderDescription,
        .Details = (From OD In db.OrderDetailTable
            Where OD.OrderID = O.OrderID
            Select New With {
                .ID = OD.OrderDetailID,
                .Description = OD.OrderDetailDescription,
                .Amount = OD.OrderDetailAmount})
        }
    ).ToList()

    Return orders
End Function

РЕДАКТИРОВАТЬ:
Ну, это безумие. Проблема, похоже, связана с проблемой VB.NET с EF.
Эта версия С# работает.

var data = db.OrderTable
    .Select(O => new Order { ID = O.OrderID, 
    Description = O.OrderDescription,
    Details = db.OrderDetailTable.Where(D => D.OrderID == O.OrderID)
        .Select(OD => new OrderDetail { Description = OD.OrderDetailDescription})})
        .ToList();  

То же самое не работает в VB.NET.

Dim data = db.OrderTable
    .Select(Function(O) New Order With {.ID = O.OrderID, 
    .Description = O.OrderDescription,
    .Details = db.OrderDetailTable.Where(Function(D) D.OrderID = O.OrderID)
        .Select(Function(OD) New OrderDetail With {.Description = OD.OrderDetailDescription})})
        .ToList()

Проблема, похоже, связана с этой работой.
https://entityframework.codeplex.com/workitem/808

РЕДАКТИРОВАТЬ:
В UrbanEsc и jameslj мне удалось получить какой-то рабочий код.
Кажется, что если свойство Order.Details является "СПИСОК", тогда код будет работать только при использовании:

Dim orders = (From O In db.OrderTable
    Select New With {
        .ID = O.OrderID,
        .Description = O.OrderDescription,
        .Details = (From OD In db.OrderDetailTable.AsEnumerable()
            Where OD.OrderID = O.OrderID
            Select New With {
                .ID = OD.OrderDetailID,
                .Description = OD.OrderDetailDescription,
                .Amount = OD.OrderDetailAmount}).ToList()
        }
    ).ToList()

Обратите внимание на "AsEnumerable" вместе с "ToList()" на деталях. Оба они требуются.

Но если я изменил свойство Order.Details на "IQueryable" или "IEnumerable", тогда я могу удалить дополнительный "ToList" и использовать AsQueryable или AsEnumerable.

Property Details As IQueryable(Of OrderDetail)

Dim orders = (From O In db.OrderTable
    Select New With {
        .ID = O.OrderID,
        .Description = O.OrderDescription,
        .Details = (From OD In db.OrderDetailTable.AsQueryable()
            Where OD.OrderID = O.OrderID
            Select New With {
                .ID = OD.OrderDetailID,
                .Description = OD.OrderDetailDescription,
                .Amount = OD.OrderDetailAmount})
        }
    ).ToList()
Теги:
linq
entity-framework

2 ответа

0
Лучший ответ
orders = db.OrderTable.Select(Function(x) New Order() With 
    {.Id = x.OrderID,
            .Description = x.OrderDescription,
            .Details = db.OrderDetailTable.Where(
                Function(y) y.OrderId = x.OrderID).ToList().Select(
                    Function(z) New OrderDetail() With
                        {.Id = z.OrderDetailId,
                         .Description = z.OrderDetailDescription,
                         .Amount = z.OrderDetailAmount}).ToList()}).ToList()
  • 0
    Этот код не работает. Возвращает следующую ошибку. "Невозможно привести тип 'System.Collections.Generic.List 1[[OrderDetail]]' to type 'System.Collections.Generic.ICollection 1 [[OrderDetail]]'. LINQ to Entities поддерживает только приведение типов примитивов или перечислений EDM «.
  • 0
    Извините, ваш код работает. Я изменил свойство Details в Collection, когда оно должно было быть List.
1

Согласно моему комментарию, вам нужно добавить.ToList() для вашего SELECT on Details.

Public Shared Function GetOrders() As List(Of Order)
    Dim db = New OrderEntities()

    Dim orders = (From O In db.OrderTable
    Select New Order With {
        .ID = O.OrderID,
        .Description = O.OrderDescription,
        .Details = (From OD In db.OrderDetailTable
            Where OD.OrderID = O.OrderID
            Select New OrderDetail With {
                .ID = OD.OrderDetailID,
                .Description = OD.OrderDetailDescription,
                .Amount = OD.OrderDetailAmount})
            .ToList()
        }
    ).ToList()

    Return orders
End Function
  • 0
    ToList () не работает. Это вернуло другую ошибку. "Невозможно привести тип 'System.Linq.IQueryable 1[[OrderDetails]]' to type 'System.Collections.Generic.IEnumerable 1 [[OrderDetails]] '. LINQ to Entities поддерживает только приведение типов примитивов EDM или перечислений."
  • 0
    Код, который вы разместили, не работает. Я скопировал и вставил непосредственно, и когда я запускаю код, я получаю «Невозможно привести тип« System.Linq.IQueryable1 [[OrderDetails]] »к типу« System.Collections.Generic.IEnumerable1 [[OrderDetails]] ». LINQ to Объекты поддерживают только приведение типов примитивов и перечислений EDM. "
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню