私はEF5 Code Firstを使用しておりTree
、ネストされたsの束である標準型構造を持っていFolder
ます。一部のフォルダには、Device
その中に があります。私がやりたいことは、フォルダーを選択して、そのフォルダーとその子フォルダー内のすべてのデバイスを見つけることです。
掘り下げた後、必要なデータを生成するには、共通テーブル式を使用する必要があるようです。残念ながら、私はこれを行う方法に本当に苦労しています。
public class Folder
{
public virtual ICollection<Folder> Children { get; set; }
public virtual ICollection<Device> Devices { get; set; }
}
public class Device
{
public virtual ICollection<Folder> PresentInFolders { get; set; }
}
この MSDN 記事GetDevicesForFolderRecursively
の作業に基づいて機能を追加しようとしました。デバイスが複数のフォルダーにある可能性があり、フォルダーのリストがあるため、私の状況では機能しないため、クエリは不完全です。folder.FolderId equals device.FolderID
public IQueryable<Device> GetDevicesForFolderRecursively(int folderID)
{
return from folder in this.FlatFolders
join device in this.Devices on folder.FolderId equals device.FolderID
where folder.FolderId == folderID
select device;
}
これが途方に暮れると、CTEをどれだけ正確に構築するかもわかりません。MSDN の記事が作成する CTE はそのように見えますが、自分のニーズに合わせて変更する方法と、これが再帰的にどのように機能するかわかりません。
context.Database.ExecuteSqlCommand(@"CREATE VIEW [dbo].[ManagerEmployees]
AS
WITH cte ( ManagerEmployeeID, EmployeeID )
AS ( SELECT EmployeeID ,
EmployeeID
FROM dbo.Employees
UNION ALL
SELECT e.EmployeeID ,
cte.EmployeeID
FROM cte
INNER JOIN dbo.Employees AS e ON e.ReportsToEmployeeID = cte.ManagerEmployeeID
)
SELECT ISNULL(EmployeeID, 0) AS ManagerEmployeeID ,
ISNULL(ManagerEmployeeID, 0) AS EmployeeID
FROM cte");
アップデート
CTE クエリをこの状態にすることはできましたが、まだうまくいきません。それは理解できAS ( SELECT FolderId , [EstateManagerService].dbo.Devices.DeviceSerial
ず、そこにどのような値が含まれているのかわかりませんか?
CREATE VIEW [dbo].[ManagerEmployees]
AS
WITH cte ( FolderID, DeviceID )
AS ( SELECT FolderId ,
[EstateManagerService].dbo.Devices.DeviceSerial
FROM [EstateManagerService].dbo.Folders
UNION ALL
SELECT e.Folder_FolderId,
cte.FolderID
FROM cte
INNER JOIN [EstateManagerService].dbo.FolderDevices AS e ON e.Folder_FolderId = cte.FolderID
)
SELECT ISNULL(DeviceID, 0) AS FolderID ,
ISNULL(FolderID, 0) AS DeviceID
FROM cte