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 を使用して同じことを行うにはどうすればよいですか?

アップデート

これらは、最初に EF コードを使用する私の Poco である私のクラスです。

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

@ゲルト

これは、ソリューション .Any() コード用に EF によって生成された SQL です。

{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

これまでの 2 つの回答は、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() }

( 2 つの get/set プロパティとNodeを持つクラスを使用)。IdHasChildren

于 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 に答える