У меня есть следующий код, содержащий операторы LINQ:
public async Task<HashSet<long>> GetMembersRecursive(IEnumerable<long> groupIds)
{
var containsGroupId = InExpression<Group>("Id", groupIds);
var containsParentId = InExpression<RecursiveGroupModel>("ParentId", groupIds);
var groupIdsArray = groupIds as long[] ?? groupIds.ToArray();
return new HashSet<long>(await MyContext
.Groups
.Where(containsGroupId)
.Select(a => new
{
Members = MyContext
.ViewWithRecursiveGroups
.Where(containsParentId)
.SelectMany(c => c.Group.Members)
.Union(a.Members)
.Where(b => !b.User.IsActive)
})
.SelectMany(a => a.Members.Select(b => b.MemberId))
.Distinct()
.ToListAsync());
}
private static Expression<Func<T, bool>> InExpression<T>(string propertyName, IEnumerable<long> array)
{
var p = Expression.Parameter(typeof(T), "x");
var contains = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
.Single(x => x.Name == "Contains" && x.GetParameters().Length == 2)
.MakeGenericMethod(typeof(long));
var property = Expression.PropertyOrField(p, propertyName);
var body = Expression.Call(
contains
, Expression.Constant(array)
, property
);
return Expression.Lambda<Func<T, bool>>(body, p);
}
Я получаю ошибку:
Microsoft.EntityFrameworkCore: Processing of the LINQ expression 'DbSet<RecursiveGroupModel>
.Where(b => __groupIdsArray_1
.Contains(b.ParentId))
.SelectMany(c => c.Group.GroupMembers)
.Union((MaterializeCollectionNavigation(
navigation: Navigation: Group.GroupMembers,
subquery: (NavigationExpansionExpression
Source: DbSet<GroupMember>
.Where(l0 => EF.Property<Nullable<long>>(l, "Id") != null && EF.Property<Nullable<long>>(l, "Id") == EF.Property<Nullable<long>>(l0, "GroupId1"))
PendingSelector: l0 => (NavigationTreeExpression
Value: (EntityReference: GroupMember)
Expression: l0)
)
.Where(i => EF.Property<Nullable<long>>((NavigationTreeExpression
Value: (EntityReference: Group)
Expression: l), "Id") != null && EF.Property<Nullable<long>>((NavigationTreeExpression
Value: (EntityReference: Group)
Expression: l), "Id") == EF.Property<Nullable<long>>(i, "GroupId1"))))' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
Представление:
CREATE VIEW [dbo].[View_WithRecursiveGroups] AS
WITH RecursiveGroups (GroupId, ParentId) AS
(
SELECT Id, ParentId
FROM Group
WHERE ParentId IS NOT NULL
UNION ALL
SELECT Group.Id, t.ParentId
FROM GroupTree t
JOIN Group ON t.GroupId = Group.ParentId
)
SELECT * FROM RecursiveGroups
Извинения в заранее, если некоторые имена переменных не совпадают - мне пришлось провести санитарную обработку перед публикацией.
Я понимаю, что он не может преобразовать код в SQL, и поэтому он просит меня перечислить рано или переписать так, чтобы он мог быть переведен. Я устал переставлять запрос и разбивать его на более мелкие запросы, но SelectMany
в рекурсивном представлении, по-видимому, невозможно преобразовать в SQL.
Есть ли способ заставить это работать в база данных? Или я поступаю совершенно неправильно?