Reputation: 951
Background: I would like to use System.Linq.Dynamic library to post In/Contains query to MS SQL
Please note I am trying to use System.Linq.Dynamic in generic function so that I could apply customer filter to any class having CustomerId(integer) property. Also CustomerId property could be nullable
All SO posts redirects me to this solution. After implementing the same I keep getting this exception: "No generic method 'Contains' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic."
And now this is how my code looks like:
public static IQueryable<T> ApplyCustomerFilter<T>(this IQueryable<T> collection, int[] customerIds)
{
return collection.Where("@0.Contains(outerIt.CustomerId)", customerIds);
}
public class MyUser : IdentityUser
{
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
public int? CustomerId { get; set; }
[ForeignKey(nameof(CustomerId))]
public virtual Customer Customer { get; set; }
}
Could you please guide me where I am going wrong?
Upvotes: 4
Views: 2988
Reputation: 101483
Because your MyUser.CustomerId
property is nullable - you should pass nullable int array as customerIds
in this case. For example:
public static IQueryable<T> ApplyCustomerFilter<T>(
this IQueryable<T> collection,
int?[] customerIds) { // < - note here
return collection.Where("@0.Contains(outerIt.CustomerId)", customerIds);
}
or convert passed array to array of nullable ints:
public static IQueryable<T> ApplyCustomerFilter<T>(
this IQueryable<T> collection,
int[] customerIds) {
return collection.Where("@0.Contains(outerIt.CustomerId)",
customerIds.Cast<int?>()); // <- note here
}
Alternatives proposed by Ivan Stoev in comments (with them customerIds
array can be regular int[]
array, no need for it to be array of nullables):
"@0.Contains(outerIt.CustomerId.Value)"
And this one will work in both cases (whether CustomerId
is nullable or not):
"@0.Contains(Int32(outerIt.CustomerId))"
Upvotes: 5