Reputation: 34297
I'm getting the exception: Method not supported: All
on the last line, below:
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);
}
Is there another option to use instead of All()
, or do I need to bring back the results and loop through them in memory?
public class ApplicationWithOverrideVariableGroup : EntityBase
{
// More code here
public List<string> CustomVariableGroupIds { get; set; }
// More code here
}
Upvotes: 1
Views: 648
Reputation: 5573
In Raven.Client 3.0 there is a ContainsAll
extension method which seem to be what you are searching for.
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();
Upvotes: 0
Reputation: 16796
One problem that I see is that you are not using the correct overloading of .All
.
That is, you are using appWithGroup.CustomVariableGroupIds.Contains
which is a method group, and as such can be converted to delegate type Func<..., bool>
, but not to the Expression<Func<..., bool>>
that is required by Queryable.All
. Because of that, you are actually using Enumerable.All
, which cannot be supported by a LINQ query provider that wants to translate the query expression.
However, you can write your All
clause as a lambda expression instead, and then the correct overload will be called:
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.All(cvg => appWithGroup.CustomVariableGroupIds.Contains(cvg));
Upvotes: 0
Reputation: 27944
You can translate All to not Any like:
summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.All(appWithGroup.CustomVariableGroupIds.Contains);
to
!summary.ApplicationWithOverrideVariableGroup.CustomVariableGroupIds.Any(x => !appWithGroup.CustomVariableGroupIds.Contains(x));
Upvotes: 0
Reputation: 10708
One option (albeit possibly inefficient) is that you can always pull the query into memory and then perform .All
(or any other Linq method) because the records are already loaded into the application space.
To do this in most cases, you just add .AsEnumerable()
on your IQueyable
object. Because extension methods are defined statically against the specific type, this means you'll be using the Enumerable
extension methods, all of which use a foreach
, and thus the query evaluates in-memory.
In this case, it may take some restructuring since you're returning a where clause - such an implementation would have to attach this behaviour to the building of the whole query.
Upvotes: 1