System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

IN Clause with Vogen (ValueObjects) types

Open mkalinski93 opened this issue 1 year ago • 1 comments

Hey,

I´m using this project in combination with EntityFramework Core and Vogen. I came across one small issue that when I´m using a .Where statement with a value object created by Vogen, the "IN" method cannot be used as the type cannot be parsed.

For example:

I need to find records that are in a list of RecordId´s. That type is generated by Vogen and is containing a Value field with a Guid. In Vogen, you typically create instances like that:

RoleId id = RoleId.From(Guid value);

I´ve tried these expression but with no success.

// Fails as the type does not implement with "IConvertible"
options.Filter = "id in (Guid(\"532eaef3-16c8-4ef2-b19a-d4dc122f7f15\"))";
// Fails: "Operator '==' incompatible with operand types 'RoleId' and 'String'",
options.Filter = "id in (\"532eaef3-16c8-4ef2-b19a-d4dc122f7f15\")";
// Success
options.Filter = "id eq \"532eaef3-16c8-4ef2-b19a-d4dc122f7f15\"";

I know this case is very specific and absolutely not related to this library, but I would really like to get to know if there´s something I can do to make this possible.

mkalinski93 avatar Nov 07 '24 13:11 mkalinski93

I´ve tested a few more scenarios and it seems that I have to explicitely use a typed collection for this case:

//This works, as the List is of type RoleId
List<RoleId> ids = new List<RoleId> { RoleId.Administrator, RoleId.Manager, RoleId.User };
var test = await customQuery.Where("Id in @0", ids).ToListAsync();
//This does not work
List<string> stringIds = ids.Select(x => x.Value.ToString()).ToList();
var test = await customQuery.Where("Id in @0", stringIds).ToListAsync();
System.InvalidOperationException: 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. 
//This does not work
List<Guid> guidIds = ids.Select(x => x.Value).ToList();
var test = await customQuery.Where("Id in @0", guidIds).ToListAsync();
System.InvalidOperationException: 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. 
//This does not work
List<object> objectIds = ids.Select(x => (object)x.Value).ToList();
var test = await customQuery.Where("Id in @0", objectIds).ToListAsync();
System.InvalidOperationException: 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. 
//This does not work
string testString = string.Join(", ", ids.Select(x => $"Guid(\"{x.Value}\")"));
var test = await customQuery.Where("Id in @0", testString).ToListAsync();
System.InvalidOperationException: 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. 

Since I´m using this library in order to filter my BackEnd from FrontEnd values, I don´t have any explicit type to set for the specify for the collection. But I´m struggling to find an answer that "Id eq 'key'" works, but "@0.Contains(Id) or Id IN (@0)" does not.

mkalinski93 avatar Nov 08 '24 09:11 mkalinski93