我想轉換以下查詢:
(from documentType in entitySet
join userGroupId in Repository.ConvertToBigIntTable(userGroupIds, "userGroupId")
on documentType.Id equals userGroupId.Id into UserGroupIds
from userGroupId in UserGroupIds.DefaultIfEmpty()
join documentTypePermission in Repository.DocumentTypePermissions
on documentType.Id equals documentTypePermission.DocumentTypeId
join userSelectionParam in Repository.UserSelectionParams
on documentTypePermission.UserSelectionId equals userSelectionParam.Id
where documentTypePermission.IsActive &&
((userSelectionParam.UserGroupId != null && userGroupId.Id != null)
|| (userSelectionParam.UserId != null && userSelectionParam.UserId == CurrentUserId))
select documentTypePermission);
像這樣:
var query =
from documentType in entitySet
from userGroupId in Repository.ConvertToBigIntTable(userGroupIds, "userGroupId")
.Where(userGroupId => documentType.Id == userGroupId.Id)
.DefaultIfEmpty()
join documentTypePermission in Repository.DocumentTypePermissions
on documentType.Id equals documentTypePermission.DocumentTypeId
join userSelectionParam in Repository.UserSelectionParams
on documentTypePermission.UserSelectionId equals userSelectionParam.Id
....
筆記:
我已經準備好使用攔截運算式樹評估的設定
QueryTranslationPreprocessor我需要使用第一個 linq 生成輸出等的邏輯
.Call,.SelectMany然后將其轉換為上面顯示的第二個 linq 查詢需要注意的是,運算式引擎在內部生成了如此多的匿名型別,以至于我無法撰寫一個通用代碼來滿足具有此類 groupjoins 的 linq 的不同情況
這樣做的原因:
GroupJoin社區尚未準備好解決 EF Core 6 中的幾種問題我不能直接對 Linq 查詢進行更改,因為它們有 1000 個并且在幾個地方
uj5u.com熱心網友回復:
因此,在評估多個選項之后,執行上述操作的最佳方法如下所示 VisitMethodCall(MethodCallExpression node)
if (node.Method.DeclaringType == typeof(Queryable) && node.Method.Name == nameof(Queryable.GroupJoin) && node.Arguments.Count == 5)
{
var outer = Visit(node.Arguments[0]);
var inner = Visit(node.Arguments[1]);
var outerKeySelector = Visit(node.Arguments[2]).UnwrapLambdaFromQuote();
var innerKeySelector = Visit(node.Arguments[3]).UnwrapLambdaFromQuote();
var resultSelector = Visit(node.Arguments[4]).UnwrapLambdaFromQuote();
var outerKey = outerKeySelector.Body.ReplaceParameter(outerKeySelector.Parameters[0], resultSelector.Parameters[0]);
var innerKey = innerKeySelector.Body;
var keyMatch = MatchKeys(outerKey, innerKey);
var innerQuery = Expression.Call(
typeof(Queryable), nameof(Queryable.Where), new[] { innerKeySelector.Parameters[0].Type },
inner, Expression.Lambda(keyMatch, innerKeySelector.Parameters));
var asEnumerableInnerQuery = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.AsEnumerable),
new Type[] { innerKeySelector.Parameters[0].Type }, innerQuery);
var resultTypes = resultSelector.Parameters.Select(p => p.Type).ToArray();
var tempProjectionType = typeof(Tuple<,>).MakeGenericType(resultTypes);
var tempProjection = Expression.New(
tempProjectionType.GetConstructor(resultTypes),
new Expression[] { resultSelector.Parameters[0], asEnumerableInnerQuery },
tempProjectionType.GetProperty("Item1"), tempProjectionType.GetProperty("Item2"));
var tempQuery = Expression.Call(
typeof(Queryable), nameof(Queryable.Select), new[] { outerKeySelector.Parameters[0].Type, tempProjectionType },
outer, Expression.Lambda(tempProjection, resultSelector.Parameters[0]));
var tempResult = Expression.Parameter(tempProjectionType, "p");
var projection = resultSelector.Body
.ReplaceParameter(resultSelector.Parameters[0], Expression.Property(tempResult, "Item1"))
.ReplaceParameter(resultSelector.Parameters[1], Expression.Property(tempResult, "Item2"));
var query = Expression.Call(
typeof(Queryable), nameof(Queryable.Select), new[] { tempProjectionType, projection.Type },
tempQuery, Expression.Lambda(projection, tempResult));
return query;
}
return base.VisitMethodCall(node);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/427145.html
標籤:林克 实体框架核心 链接到实体 表达式树 ef-core-6.0
下一篇:查詢哈希表鍵LINQ運算式C#
