将公用表表达式与实体框架5一起使用

时间:2013-08-19 13:34:49

标签: sql entity-framework common-table-expression

我正在使用EF5 Code First,我有一个标准的Tree类型结构,它是一堆嵌套的Folder。有些文件夹里面有Device个。我想要做的是能够选择一个文件夹,找到该文件夹​​及其子文件夹中的所有设备。

经过一番挖掘后,似乎我需要使用Common Table Expressions来生成我需要的数据。不幸的是,我真的在努力解决这个问题。

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; }
 }

我尝试根据this MSDN article上的工作添加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

0 个答案:

没有答案