Do you want to request a feature or report a bug?
Bug
What is the current behavior?
When attempting to use the "ContainsOr" extension method with an ItemReferenceListField fieldtype an exception is thrown:
public IQueryable<SearchResultItem> ShapeQuery1(IProviderSearchContext context, IQueryable<SearchResultItem> query, IBaseSearchPageConfigurationItem config)
{
var cfg = config as IPersonListingItem;
var q = context.GetQueryable<IBasePersonItem>();
if (cfg.PersonTypeFilter.HasValue)
// where k.PersonType is an IItemReferenceListField field
q = q.ContainsOr(k => k.PersonType, cfg.PersonTypeFilter.TargetIds.ToArray());
return q.Cast<SearchResultItem>().AsQueryable();
}
System.InvalidOperationException: 'No method 'Contains' on type 'System.Linq.Enumerable' is compatible with the supplied arguments.'
From what I can tell, this occurs because the initial attempt to resolve the 'Contains' method on IItemReferenceListField fails to find it (line 70). Even though IItemReferenceListField has the base interface ICollection, it does not find it because it is not explicitly defined on IItemReferenceListField.
In order to resolve this issue, I came up with 2 solutions.
The simple hack was to just add the 'Contains' method to the IItemReferenceListField interface using the 'new' keyword to hide the underlying 'Contains' method from ICollection
public interface IItemReferenceListField : ICollection<ID>, IFieldType
{
//
// ...
//
// hides 'Contains' from ICollection<ID>
new bool Contains(ID item);
}
This worked, but is somewhat of a hack.. and it is specific to just IItemReferenceListField.
I added another else-if block to the ContentSearchQueryExtensions.cs class which checks the base interfaces of a type as a secondary fallback before resorting to using the 'Contains' method from IEnumerable.
if (typeOfTKey.GetMethods().Any(m => m.Name.Equals(methodName)))
{
var method = typeOfTKey.GenericTypeArguments.Any() ? typeOfTKey.GetMethod(methodName, typeOfTKey.GenericTypeArguments) : typeOfTKey.GetMethod(methodName);
// Useful Large Comment...
expressions = constants.Select(constant => Expression.Call(keySelector.Body, method, constant));
}
else if (typeOfTKey.GetInterfaces().Any(i => i.GetMethods().Any(m => m.Name.Equals(methodName))))
{
// Same as above except, check base interfaces of the typeOfTKey for the "Contains" method
var baseType = typeOfTKey.GetInterfaces().First(i => i.GetMethods().Any(m => m.Name.Equals(methodName)));
var method = baseType.GenericTypeArguments.Any() ? baseType.GetMethod(methodName, baseType.GenericTypeArguments) : baseType.GetMethod(methodName);
expressions = constants.Select(constant => Expression.Call(keySelector.Body, method, constant));
}
else
{
// Useful Large Comment...
var typeArgs = typeOfTKey.IsArray ? new[] { typeOfTKey.GetElementType() } : typeOfTKey.GenericTypeArguments;
expressions = constants.Select(constant => Expression.Call(typeof(Enumerable), methodName, typeArgs, keySelector.Body, constant));
}
If this looks okay, I can send in a PR.
If the current behavior is a bug, please provide the steps to reproduce.
Setup a synthesis item with a ItemReferenceListField
Run a content search like the snippet above
What is the expected behavior?
I expected it to work with the ItemReferenceListField field type.
Please mention your Sitecore version and Synthesis version.
Sitecore version 9.1
Synthesis version 9.1.0.2-beta1
Do you want to request a feature or report a bug? Bug
What is the current behavior? When attempting to use the "ContainsOr" extension method with an ItemReferenceListField fieldtype an exception is thrown:
The exception is occurs in the ContentSearchQueryExtensions.cs class line 103:
From what I can tell, this occurs because the initial attempt to resolve the 'Contains' method on IItemReferenceListField fails to find it (line 70). Even though IItemReferenceListField has the base interface ICollection, it does not find it because it is not explicitly defined on IItemReferenceListField.
In order to resolve this issue, I came up with 2 solutions.
This worked, but is somewhat of a hack.. and it is specific to just IItemReferenceListField.
If this looks okay, I can send in a PR.
If the current behavior is a bug, please provide the steps to reproduce.
What is the expected behavior?
I expected it to work with the ItemReferenceListField field type.
Please mention your Sitecore version and Synthesis version. Sitecore version 9.1 Synthesis version 9.1.0.2-beta1