2

我想获取其父为 null 的所有模块,这意味着所有根模块。

此外,我希望每个模块都知道它是否有孩子。

我需要这个功能,因为根模块显示在延迟加载的模块树中。

这样它对 SQL 的工作很快:

SELECT 
   Id, 
   CASE WHEN EXISTS (SELECT NULL FROM Module m2 WHERE m2.ParentId = module.Id) THEN 1 
        ELSE 0 
   END AS HasChildren 
FROM Module 
WHERE ParentId IS NULL

如何使用 EF 5 做同样的事情?

更新

这些是我的类,它们是我的 Poco 首先使用 EF 代码:

public class Module
    {
        public Module()
        {
            Children = new List<Module>();
        }

        // PK
        public int ModuleId { get; set; }
        public string Name { get; set; }
        public List<Module> Children { get; set; }

        // FK
        public int MachineId { get; set; }
        public Machine Machine { get; set; }
    }

    public class Machine
    {
        // PK
        public int MachineId { get; set; }
        public string Name { get; set; }
    }

更新2

@Gert

这是 EF 为您生成的 sql 解决方案 .Any() 代码:

{SELECT 
[Extent1].[ModuleId] AS [ModuleId], 
[Extent1].[Name] AS [Name], 
CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[Module] AS [Extent2]
    WHERE [Extent1].[ModuleId] = [Extent2].[Module_ModuleId]
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[Module] AS [Extent3]
    WHERE [Extent1].[ModuleId] = [Extent3].[Module_ModuleId]
)) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[Module] AS [Extent1]
WHERE ([Extent1].[ParentId] IS NULL) AND ([Extent1].[MachineId] = @p__linq__0)}

您的 linq 查询永远不会为 HasChildren 属性返回 TRUE,因为我以前的查询看起来不同:

context.Modules.SqlQuery("SELECT Module.ModuleId, Module.Name, case when Exists(select null from Module m where m.ParentID = Module.ModuleId) " +
"then 1 else 0 end as HasChildren FROM Module WHERE Module.ParentId Is Null AND Module.MachineId = @MachineId ORDER BY HierarchyIndex",
new SqlParameter("MachineId",machineId)).ToList();

在 EF 生成的“你的”sql 语句中,我错过了重要的 m.ParentId = Module.ModuleId 比较。你做 Extend1.ModuleId = Extend2.Module_ModuleId。

好像有什么不对劲。

4

2 回答 2

1

到目前为止,这两个答案都没有考虑到 EF 查询中对 CLR 方法的调用无法转换为 SQL 并且 EF 会引发异常的事实。

因此,您必须使用 EF 可以转换为 SQL 的方法来解决它。现在幸运的是,您的查询不是递归的(例如获取层次结构的所有级别),而是非常简单:

from m in context.Modules
          where m.ParentId == null
          select new { m.Id, HasChildren = m.Children.Any() }

如您所见,我必须对您的模型做出一些假设(这就是我问的原因)。主要的是Module具有导航属性Childeren(1:n)。你可以没有,但你必须(组)加入Modules

from m in context.Modules.Where(x => x.ParentId == null)
          join child in context.Modules on m.Id equals child.ParentId
              into groupJoin
          select new Node { m.Id, HasChildren = groupJoin.Any() }

Node具有两个 get/set 属性Id和的类HasChildren)。

于 2013-01-24T09:12:37.117 回答
-2
public void ListModule()
        {
            var raw= from m1 in db.Module
                       where m1.ParentId == null
                       select new { m1.ParentId, wanted = this.test(m1.ParentId) };

        }

public int test(string para)
{
    var raw = from c in db.Module
              where c.ParentId == para
              select c;
    if (raw.Count() != 0)
        return 1;
    else
        return 0;
}
于 2013-01-24T03:52:01.727 回答