[英]C#/Linq How to get all records by ParentId and then by FolderId recursively
我有以下表格設置:
我需要獲取與某個ParentId
相關聯的所有文件夾(僅直接子項)我還需要能夠傳入一個FolderId
,然后獲取記錄的完整路徑以從頂層開始到達該FolderId
(null parent ID)
我試過.SelectMany()
,但我有這個錯誤:
無法從用法中推斷出方法“Enumerable.SelectMany<TSource, TResult>(IEnumerable, Func<TSource, IEnumerable>)”的類型 arguments。 嘗試明確指定類型 arguments
public async Task<IList<FolderDTO>> GetFullPathByFolderId(int? parentId, bool onlyDirectChildren)
{
var allFolders = await GetAllFolders(false).ConfigureAwait(false);
return allFolders.Where(x => x.ParentId == parentId)
.Union(allFolders.Where(x => x.ParentId == parentId)
.SelectMany(y => GetFullPathByFolderId(y.FolderId)));
}
因此,如果傳入 null 的ParentId
,我需要返回 4 條記錄:文件夾名稱,依次為:Private、Public、Shared、Private Deleted。
如果通過了FolderId
,我需要返回 2 條記錄:文件夾名稱,依次為:無標題目錄、公共。
有沒有辦法將它組合成一個或兩個方法?
CREATE TABLE [dbo].[Folders](
[FolderId] [int] IDENTITY(1,1) NOT NULL,
[ParentId] [int] NULL,
[FolderName] [varchar](150) NOT NULL,
[FolderTypeId] [int] NOT NULL,
[IsHidden] [bit] NOT NULL,
[DateModified] [datetime] NOT NULL,
[ModifiedBy] [int] NOT NULL,
[DateSoftDeleted] [datetime] NULL,
[SoftDeletedBy] [int] NULL,
CONSTRAINT [PK_Folders] PRIMARY KEY CLUSTERED
(
[FolderId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
更新代碼:
這是一些代碼。
我想將FolderId
1
傳遞給 LINQ/C# 調用並返回名稱: Private和Private1
namespace App
{
/// <summary>
/// FolderTypeDTO
/// </summary>
public class FolderTypeDTO
{
/// <summary>
/// Gets or sets the folder type identifier.
/// </summary>
/// <value>
/// The folder type identifier.
/// </value>
public int FolderTypeId { get; set; }
/// <summary>
/// Gets or sets the name of the folder type.
/// </summary>
/// <value>
/// The name of the folder type.
/// </value>
public string FolderTypeName { get; set; }
}
}
namespace App
{
using System;
/// <summary>
/// Folder DTO
/// </summary>
public class FolderDTO
{
/// <summary>
/// Gets or sets the folder identifier.
/// </summary>
/// <value>
/// The folder identifier.
/// </value>
public int FolderId { get; set; }
/// <summary>
/// Gets or sets the parent identifier.
/// </summary>
/// <value>
/// The parent identifier.
/// </value>
public int? ParentId { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance has sub folders.
/// </summary>
/// <value>
/// <c>true</c> if this instance has sub folders; otherwise, <c>false</c>.
/// </value>
public bool HasSubFolders { get; set; }
/// <summary>
/// Gets or sets the name of the folder parent.
/// </summary>
/// <value>
/// The name of the folder parent.
/// </value>
public string FolderParentName { get; set; }
/// <summary>
/// Gets or sets the name of the folder.
/// </summary>
/// <value>
/// The name of the folder.
/// </value>
public string FolderName { get; set; }
/// <summary>
/// Gets or sets the folder type identifier.
/// </summary>
/// <value>
/// The folder type identifier.
/// </value>
public int FolderTypeId { get; set; }
/// <summary>
/// Gets or sets the name of the folder type.
/// </summary>
/// <value>
/// The name of the folder type.
/// </value>
public string FolderTypeName { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is hidden.
/// </summary>
/// <value>
/// <c>true</c> if this instance is hidden; otherwise, <c>false</c>.
/// </value>
public bool IsHidden { get; set; }
/// <summary>
/// Gets or sets the level.
/// </summary>
/// <value>
/// The level.
/// </value>
public int Level { get; set; }
/// <summary>
/// Gets or sets the date modified.
/// </summary>
/// <value>
/// The date modified.
/// </value>
public DateTime DateModified { get; set; }
/// <summary>
/// Gets or sets the modified by.
/// </summary>
/// <value>
/// The modified by.
/// </value>
public int ModifiedBy { get; set; }
/// <summary>
/// Gets or sets the name of the modified by.
/// </summary>
/// <value>
/// The name of the modified by.
/// </value>
public string ModifiedByName { get; set; }
/// <summary>
/// Gets or sets the date soft deleted.
/// </summary>
/// <value>
/// The date soft deleted.
/// </value>
public DateTime? DateSoftDeleted { get; set; }
/// <summary>
/// Gets or sets the soft deleted by.
/// </summary>
/// <value>
/// The soft deleted by.
/// </value>
public int? SoftDeletedBy { get; set; }
/// <summary>
/// Gets or sets the name of the soft deleted by.
/// </summary>
/// <value>
/// The name of the soft deleted by.
/// </value>
public string SoftDeletedByName { get; set; }
}
}
var folderTypeList = new List<FolderTypeDTO>
{
new FolderTypeDTO
{
FolderTypeId = 1,
FolderTypeName = "Private"
},
new FolderTypeDTO
{
FolderTypeId = 2,
FolderTypeName = "Public"
},
new FolderTypeDTO
{
FolderTypeId = 3,
FolderTypeName = "Shared"
},
};
var folderList = new List<FolderDTO>
{
new FolderDTO
{
FolderId = 1,
ParentId = null,
FolderName = "Private",
FolderTypeId = 1,
IsHidden = false,
DateModified = DateTime.UtcNow,
ModifiedBy = 107 // my user id in our app
},
new FolderDTO
{
FolderId = 2,
ParentId = null,
FolderName = "Public",
FolderTypeId = 2,
IsHidden = false,
DateModified = DateTime.UtcNow,
ModifiedBy = 107 // my user id in our app
},
new FolderDTO
{
FolderId = 3,
ParentId = 1,
FolderName = "Private 1",
FolderTypeId = 1,
IsHidden = false,
DateModified = DateTime.UtcNow,
ModifiedBy = 107 // my user id in our app
}
};
謝謝你的代碼。 現在很容易得到結果。
從有助於通過parentID
生成一組遞歸FolderDTO
對象的查找開始。
ILookup<int?, FolderDTO> lookup = folderList.ToLookup(x => x.ParentId);
現在我們可以編寫一個遞歸方法來返回具有提供的parentID
的完整的FolderDTO
對象集。
IEnumerable<FolderDTO> GetHierarchically(int? parentId) =>
from x in lookup[parentId]
from y in GetHierarchically(x.FolderId).StartWith(x)
select y;
現在這是一個相當簡單的例子,通過Concat
和Join
來獲得你需要的結果。
IEnumerable<string> GetFolderNamesHierarchicallyByIdAndType(int parentId, string folderTypeName) =>
from x in
Enumerable
.Concat(
folderList.Where(f => f.FolderId == parentId),
GetHierarchically(parentId))
join y in folderTypeList on x.FolderTypeId equals y.FolderTypeId
where y.FolderTypeName == folderTypeName
select x.FolderName;
這可以這樣調用:
string[] names = GetFolderNamesHierarchicallyByIdAndType(1, "Private").ToArray();
我從您的樣本數據中得到的結果是:
Private
Private 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.