我试图让所有的父母与一个对象相关联。有些对象有父对象,而其他对象可能没有。我正在使用这些数据来创建面包屑。
{
public Folder()
{
Children = new List<Folder>();
Files = new List<File>();
FolderUserNotifications = new List<FolderUserNotification>();
}
public Guid ClientId { get; set; }
public Guid? ParentId { get; set; }
[Required]
[RegularExpression(@"^[^\\\./:\*\?\""<>\|]{1}[^\\/:\*\?\""<>\|]{0,254}$", ErrorMessage = @"The following special characters are not allowed: \ / * : ? "" < > | """)]
public string Name { get; set; }
public string CreatedBy { get; set; }
public virtual Folder Parent { get; set; }
public virtual List<Folder> Children { get; set; }
public virtual List<File> Files { get; set; }
public virtual List<FolderUserNotification> FolderUserNotifications { get; set; }
}
public async Task<Folder> GetFolderFileListByClientIdParentId(Guid clientId, Guid folderId)
{
using dbContext db = _contextFactory.CreateDbContext();
{
Folder result = await db.Folders.Where(y => y.Id == folderId)
.Include(x => x.Children)
.ThenInclude(i => i.Files)
.FirstOrDefaultAsync();
return result;
}
}
public Folder GetFoldersParentIds(Guid folderId)
{
using dbContext db = _contextFactory.CreateDbContext();
{
Folder folderWithParents = db.Folders.Where(i => i.Id == folderId).Include(i => i.Parent).ThenInclude(i => i.Parent).FirstOrDefault();
return folderWithParents;
}
}
GetFolderFileListByClientIdParentId 是我在代码中其他地方使用的调用。它带回了所有的孩子,我能够对其进行所有需要做的操作。 GetFoldersParentIds 是我遇到麻烦的一个。如果我继续添加 .include(i=> i.Parent) 它将继续获取所有父母。代码中的文件夹现在在其父级和其父级中获取文件夹,因为这两个包含。我怎样才能获得所有这些而不需要放入 100 个 .includes?
据我所知,仅使用 LINQ 无法做到这一点。
您有以下选择
如果您不使用 SQL Server,请使用 HierarchyId 或相应的数据类型。然后你可以使用 EF 选项调用 SQL 函数来获取整个层次结构
将所有内容拉到内存中,提前订购并缓存。对于文件夹来说可能不是一个好的选择,但通常适用于类别和子类别之类的东西。显然,这有多可行取决于您拥有多少物品
创建一个 SQL 视图或在使用 CTE 的源中编写查询(如果您使用的数据库与 SQL Server 不同,则使用相应的功能),然后将其映射到一个类并以这种方式执行查询
您可以选择递归地发出更多查询。如果你的层次结构很浅,那可能会起作用。在使用这些 ID 发出单个查询之前,您需要收集下一级的 ID,以减少查询数量。尽管如此,您仍然会有与层次结构的深度一样多的查询,这听起来不太好
在我看来,HierarchyId 最适合您的情况,但不能确定