【问题标题】:How can I use this T-SQL query in LINQ / Entity Framework?如何在 LINQ / Entity Framework 中使用此 T-SQL 查询?
【发布时间】:2009-08-06 21:30:26
【问题描述】:

我只处理一个数据库表/实体对象:NodePath。

给定一个特定的节点,我想根据这个查询只获取它所有节点路径的一个子集:

select
    *
from
    NodePath
where
    NodeId = @GivenNodeId and
    Id in
    (
        --active paths
        select
            a.Id
        from
            NodePath a join
        (
                select
                    [Path],
                    max(Created) as Created
                from
                    NodePath
                group by
                    [Path]
        ) b on
        a.[Path] = b.[Path] and
        a.Created = b.Created
    )

如何在我的 VB.NET 应用程序中执行此操作?

Dim AllPaths = GivenNode.NodePaths.OrderByDescending(Function(p) p.Created)

Dim ActivePaths = ???

【问题讨论】:

    标签: .net linq tsql entity-framework stored-procedures


    【解决方案1】:

    我相信我已经正确翻译了该 SQL,但如有必要,我可以进行更改。这是为每个常见的Path 选择一个NodePath(基于最大的Created),只要它与NodeId 匹配。

    C#解决方案:

    var nodePaths = (from p in context.NodePaths
                     group p by p.Path into g
                     select g.OrderByDescending(i => i.Created).First()
                     ).Where(p => p.NodeId == givenNodeId);
    

    VB.NET 解决方案(我认为,不是我的主要语言):

    Dim nodePaths = (From p In context.NodePaths _
                     Group p By p.Path Into Group _
                     Select Group.OrderByDescending(Function(i) i.Created).First() _
                     ).Where(Function(p) p.NodeId = givenNodeId)
    

    【讨论】:

    • 这有点奇怪,因为它首先抓取具有最大 Created 的 NodePath,然后进行过滤。这似乎是 SQL 查询的工作原理,这就是我这样写的原因。
    • 另外,我在写这篇文章时考虑到了 LinqToSql,但我没有看到任何会导致实体框架出现问题的东西。
    • 谢谢你,瑞恩。我现在决定采用 Marcel 的存储过程建议。我知道我最终必须强迫自己更加适应 LINQ。
    • 当然!即使您对在代码中使用这样的查询感到不自在,运行它(正常运行或使用 LinqPad)可能会很有趣,只是看看它生成的查询与您当前的查询相比。
    【解决方案2】:

    您可以创建一个存储过程,然后将其添加到要调用的 EDMX(模型)中。只需右键单击并选择“从数据库更新模型”,应该有一个存储过程选项卡。另见here

    在模型浏览器中找到存储过程。

    右键单击它并选择创建函数导入。

    Entity Data Model Create Function Import http://img31.imageshack.us/img31/9100/createfunctionimport.gif

    选择返回的实体类型。 (在这种情况下:NodePath)

    在您的代码中调用函数:

    Dim ActivePaths = context.ActivePaths(GivenNode.Id)
    

    如果您想在没有存储过程的情况下执行此操作,则必须使用 LINQ 或 Entity SQL。当然是 ADO.NET :)

    【讨论】:

    • 我已经用更多步骤更新了这个答案。谢谢你,马塞尔。
    猜你喜欢
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2019-09-02
    • 2023-03-26
    相关资源
    最近更新 更多