mcintyre321 / ValueOf

Deal with Primitive Obsession - define ValueObjects in a single line (of C#).
MIT License
877 stars 40 forks source link

Contains in Linq #35

Open adria-arquimbau opened 1 year ago

adria-arquimbau commented 1 year ago

I have an issue and don't know how to solve it. Having 4 string fields from one entity I decided to change one of them "SerialNumber" to a value object.

At some point having an IQueryable I need to filter for the items that contain a similar search term, in this example details. There is no problem with using .Contains for any string fields but when I change SerialNumber to ValueObject and I don't have the Contain method anymore.

return query.Where(x =>
                x.Number.Contains(details) ||
                x.SerialNumber.Value.Contains(details) || //New field as string ValueObject
                x.Name.Contains(details) ||
                x.CarrierName.Contains(details));

I tried to use x.SerialNumber.Value.Contains(details), details.Contains(x.SerialNumber.Value) and some other approaches. And responding with the following error: Could not be translated

mcintyre321 commented 1 year ago

This might help https://github.com/mcintyre321/ValueOf/issues/28

TheM1Stery commented 1 year ago

My solution was to create explicit conversion from ValueOf object to a primitive and after that use it like this:

var entity = await _dbContext.Objects.SingleOrDefaultAsync(x => (string)x.Id! == req.Id);

This piece of code translated fine and worked like intended You can even create interface and implement it in your ValueOf classes(this uses new static abstract methods of c# 11):

public interface IConvertible<in T, out TTo> where T: IConvertible<T, TTo>
{
    static abstract explicit operator TTo(T obj);
}

You would still need to use value converter that is in the previous comment(don't need it for linq) for full ValueOf support though.