کوئری نویسی در EF Core - قسمت هشتم - کوئریهای بازگشتی
نویسنده: وحید نصیری
تاریخ: ۱۳۹۹/۰۵/۱۳ ۱۰:۴۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
namespace EFCorePgExercises.Entities
{
public class Member
{
// ...
public virtual ICollection<Member> Children { get; set; }
public virtual Member Recommender { set; get; }
public int? RecommendedBy { set; get; }
// ...
}
} var id = 27;
var entity27WithAllOfItsParents =
context.Members
.Where(member => member.MemId == id
|| member.Children.Any(m => member.MemId == m.RecommendedBy))
.ToList() //It's a MUST - get all children from the database
.FirstOrDefault(x => x.MemId == id);// then get the root of the tree
namespace EFCorePgExercises.Exercises.RecursiveQueries
{
public static class RecursiveUtils
{
public static void FindParents(Member member, List<dynamic> actualResult)
{
if (member == null || member.Recommender == null)
{
return;
}
var item = member.Recommender;
actualResult.Add(new { Recommender = item.MemId, item.FirstName, item.Surname });
if (item.Recommender != null)
{
FindParents(item, actualResult);
}
}
}
} var actualResult = new List<dynamic>(); RecursiveUtils.FindParents(entity27WithAllOfItsParents, actualResult);
var id = 1;
var entity1WithAllOfItsDescendants =
context.Members
.Include(member => member.Children)
.Where(member => member.MemId == id
|| member.Children.Any(m => member.MemId == m.RecommendedBy))
.ToList() //It's a MUST - get all children from the database
.FirstOrDefault(x => x.MemId == id);// then get the root of the tree SELECT [m].[MemId],
[m].[Address],
[m].[FirstName],
[m].[JoinDate],
[m].[RecommendedBy],
[m].[Surname],
[m].[Telephone],
[m].[ZipCode],
[m0].[MemId],
[m0].[Address],
[m0].[FirstName],
[m0].[JoinDate],
[m0].[RecommendedBy],
[m0].[Surname],
[m0].[Telephone],
[m0].[ZipCode]
FROM [Members] AS [m]
LEFT OUTER JOIN
[Members] AS [m0]
ON [m].[MemId] = [m0].[RecommendedBy]
WHERE ([m].[MemId] = 1)
OR EXISTS (SELECT 1
FROM [Members] AS [m1]
WHERE ([m].[MemId] = [m1].[RecommendedBy])
AND ([m].[MemId] = [m1].[RecommendedBy]))
ORDER BY [m].[MemId], [m0].[MemId]; namespace EFCorePgExercises.Exercises.RecursiveQueries
{
public static class RecursiveUtils
{
public static void FindChildren(Member member, List<dynamic> actualResult)
{
if (member == null)
{
return;
}
foreach (var item in member.Children)
{
actualResult.Add(new { item.MemId, item.FirstName, item.Surname });
if (item.Children != null)
{
FindChildren(item, actualResult);
}
}
}
}
} var actualResult = new List<dynamic>(); RecursiveUtils.FindChildren(entity1WithAllOfItsDescendants, actualResult);
member.Children.Any(m => member.MemId == m.RecommendedBy) ||
entity.HasOne(d => d.Reply)
.WithMany(p => p.Children)
.HasForeignKey(d => d.ReplyId); dotnet add package linq2db.EntityFrameworkCore
LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.Initialize(); LinqToDB.Data.DataConnection.TurnTraceSwitchOn();
public class MemberHierarchyCTE
{
public int ChildId { set; get; }
public int? ParentId { set; get; }
} var memberHierarchyCte =
context.CreateLinqToDbContext().GetCte<MemberHierarchyCTE>(memberHierarchy =>
{
return
(
from member in context.Members
select new MemberHierarchyCTE
{
ChildId = member.MemId,
ParentId = member.RecommendedBy
}
)
.Concat
(
from member in context.Members
from hierarchy in memberHierarchy
.InnerJoin(hierarchy => member.MemId == hierarchy.ParentId)
select new MemberHierarchyCTE
{
ChildId = hierarchy.ChildId,
ParentId = member.RecommendedBy
}
);
}); WITH [memberHierarchy] ([ChildId], [ParentId])
AS
(
SELECT
[member_1].[MemId],
[member_1].[RecommendedBy]
FROM
[Members] [member_1]
UNION ALL
SELECT
[hierarchy_1].[ChildId],
[member_2].[RecommendedBy]
FROM
[Members] [member_2]
INNER JOIN [memberHierarchy] [hierarchy_1] ON [member_2].[MemId] = [hierarchy_1].[ParentId]
)
var memberHierarchyCte =
_dbContext.CreateLinqToDbContext().GetCte<MemberHierarchyCTE>(memberHierarchy =>
{
return
(
from navbar in _dbContext.Navbars
select new MemberHierarchyCTE
{
ChildId = navbar.Id,
ParentId = navbar.ParentId,
Title = navbar.Title
}
)
.Concat
(
from nav in _dbContext.Navbars
from hierarchy in memberHierarchy
.InnerJoin(hierarchy => nav.Id == hierarchy.ParentId)
select new MemberHierarchyCTE
{
ChildId = hierarchy.ChildId,
ParentId = nav.ParentId,
Title = nav.Title
}
);
});