T-Sql转linq转换问题(订购方式)

时间:2010-11-15 13:12:46

标签: asp.net vb.net linq entity-framework linq-to-entities

我在将以下t-sql语句转换为Linq时遇到了一些问题(使用4.0实体框架)

我正在

  

无法转换类型   'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable 1'。 LINQ   实体仅支持投射   实体数据模型基元类型。

T-SQL

    SELECT 
    I.Id
    , I.Name
FROM Inventory I
WHERE I.Id in 
    (
    select top 5 applicationId 
    from LastViewed 
    group by ApplicationId, SomeUserId
    having SomeUserId = @SomeUserId
    order by Max(id) desc
    )

这就是我现在所拥有的(在Linqer的帮助下)

    Dim query As IQueryable(Of Inventory) =
        From d In ctx.Inventories
        Where
            ((From e In ctx.LastVieweds _
            Group e By _
              e.ApplicationId, _
              e.SomeUserId _
             Into g = Group _
            Where DfaitEdsId = user _
            Order By g.Max(Function(p) p.Id) Descending _
            Select New With { _
              ApplicationId _
            }).Take(5)).Contains(New With {.ApplicationId = d.Id}) _
        Select d

当我这行时它崩溃了。

query.ToList()

感谢您的时间。

1 个答案:

答案 0 :(得分:3)

你的'问题'就在你的第一行。您指定的查询将返回您尝试分配给IOrderedQueryable(Of Inventory)类型变量的IQueryable(Of Inventory)。由于延迟执行,您在query.ToList()之前没有收到错误。如果您在项目中将“选项推断”设置为on,则可以让编译器推断出类型,您的查询将类似于:

Dim query =
        From d In ctx.Inventories
        Where
            (From e In ctx.LastVieweds _
            Group e By _
              e.ApplicationId, _
              e.SomeUserId _
             Into g = Group _
            Where DfaitEdsId = user _
            Order By g.Max(Function(p) p.Id) Descending _
            Select ApplicationId Take 5 _
            ).Contains(d.Id) _
        Select d

或者您只需将query的类型更改为IOrderedQueryable(Of Inventory)

即可

注意:你在Linq to SQL中可以正常工作,但实体在转换时要严格得多。

修改 好吧,让我们试着深入研究一下。告诉我哪一行爆炸了以下内容:

Dim innerList = (From e In ctx.LastVieweds _
                Group e By _
                e.ApplicationId, _
                e.SomeUserId _
                Into g = Group _
                Where DfaitEdsId = user _
                Order By g.Max(Function(p) p.Id) Descending _
                Select ApplicationId Take 5).ToList()
Dim query = (From d In ctx.Inventories
            Where innerList.Contains(d.Id) _
            Select d).ToList()

如果枚举'ToList()'的查询过多,请不要忘记将结果略微削减。这两个变量的类型现在都是List(Of Inventory)