Я получаю исключение: Method not supported: All
в последней строке, ниже:
private static Expression<Func<InstallationSummary, bool>> GetWhereClause(ApplicationServer appServer, ApplicationWithOverrideVariableGroup appWithGroup)
{
// If we're getting matches that include CustomVariableGroups (CVGs), then the number of CVGs and the IDs must match.
return summary => summary.ApplicationServerId == appServer.Id &&
summary.ApplicationWithOverrideVariableGroup.ApplicationId == appWithGroup.Application.Id &&
summary.ApplicationWithOverrideVariableGroup != null &&
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds != null &&
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.Count == appWithGroup.CustomVariableGroupIds.Count &&
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.All(appWithGroup.CustomVariableGroupIds.Contains);
}
Есть ли другой вариант использования вместо All()
, или мне нужно вернуть результаты и пропустить их в памяти?
public class ApplicationWithOverrideVariableGroup : EntityBase
{
// More code here
public List<string> CustomVariableGroupIds { get; set; }
// More code here
}
Один из вариантов (хотя и возможно неэффективный) состоит в том, что вы всегда можете вытащить запрос в память и затем выполнить .All
(или любой другой метод Linq), поскольку записи уже загружены в прикладное пространство.
Для этого в большинстве случаев вы просто добавляете .AsEnumerable()
в свой объект IQueyable
. Поскольку методы расширения определяются статически против определенного типа, это означает, что вы будете использовать методы расширения Enumerable
, все из которых используют foreach
, и, следовательно, запрос оценивается в памяти.
В этом случае может потребоваться некоторая реструктуризация, так как вы возвращаете предложение where - такая реализация должна будет приложить это поведение к построению всего запроса.
All()
или отрицательным Any()
. Благодарю.
В Raven.Client 3.0 существует метод расширения ContainsAll
который, похоже, является тем, что вы ищете.
namespace Raven.Client.Linq
{
public static class RavenQueryableExtensions
{
// Summary:
// Implementation of the Contains ALL operatior
public static bool ContainsAll<T>(this IEnumerable<T> list, IEnumerable<T> items);
}
}
Exemple:
string[] parts
var query = session.Query<Foo>()
.Where(s => s.Keywords.ContainsAll(parts));
return query.ToList();
Вы можете перевести все, чтобы не было:
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.All(appWithGroup.CustomVariableGroupIds.Contains);
в
!summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.Any(x => !appWithGroup.CustomVariableGroupIds.Contains(x));
Одна из проблем, которые я вижу, заключается в том, что вы не используете правильную перегрузку .All
.
То есть вы используете appWithGroup.CustomVariableGroupIds.Contains
который является группой методов, и как таковой может быть преобразован в делетете тип Func<..., bool>
, но не в Expression<Func<..., bool>>
что требуется Queryable.All
. Из-за этого на самом деле вы используете Enumerable.All
, который не может поддерживаться поставщиком запросов LINQ, который хочет перевести выражение запроса.
Однако вместо этого вы можете написать предложение All
как выражение лямбда, а затем вызывается правильная перегрузка:
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.All(cvg => appWithGroup.CustomVariableGroupIds.Contains(cvg));
Method not supported: All
. Возможно, RavenDB просто пока не поддерживает это.
CustomVariableGroupIds
, вероятно, не является IQueryable
, Queryable.All
не может использоваться.
InstallationSummary
чтобы мы могли видеть, что такоеCustomVariableGroupIds
.