Skip to content

Instantly share code, notes, and snippets.

@mickdelaney
Created December 17, 2021 10:43
Show Gist options
  • Select an option

  • Save mickdelaney/be81225cf499375f9e77930fbb1559cf to your computer and use it in GitHub Desktop.

Select an option

Save mickdelaney/be81225cf499375f9e77930fbb1559cf to your computer and use it in GitHub Desktop.
Hotchocolate DDD Style Value Types and Filtering
DDD Style Value Types and Filtering
Hi Guys,
I’m trying to migrate a scalar field from String to an EmailAddress class
The EmailAddress class has a String Property called ‘Value’.
As part of the GraphQL Schema there should be a way to filter the User by EmailAddress.
```csharp
public class EmailAddress
{
public string Value { get; }
public EmailAddress() { }
public EmailAddress(string value)
{
if (value == null)
{
return;
}
Value = value.ToLowerInvariant();
}
public EmailAddress New(string value) => new EmailAddress(value);
public static readonly ValueConverter<EmailAddress, string> Converter = new
(
v => v.Value,
v => new EmailAddress(v)
);
}
```
filter type
```graphql
export type PersonFilter = {
and?: Array<PersonFilter> | null | undefined;
or?: Array<PersonFilter> | null | undefined;
email?: StringOperationFilterInput | null | undefined;
};
```
query
```graphql
{ email: { startsWith: filter } },
```
**Config**
```csharp
.BindRuntimeType<EmailAddress, StringType>()
.AddTypeConverter<string, EmailAddress>(x => new EmailAddress(x))
.AddTypeConverter<EmailAddress, string>(x => x.Value);
```
*Translates to Linq Query:*
```sql
where c.Email**.Value** != null
```
This fails as that’s not valid SQL.
**Config**
```csharp
.BindRuntimeType<EmailAddress, EmailAddressType>()
.AddTypeConverter<string, EmailAddress>(x => new EmailAddress(x))
.AddTypeConverter<EmailAddress, string>(x => x.Value);
```
Fails at runtime
Message:Unexpected Execution Error
System.ArgumentException: Method 'Boolean StartsWith(System.String)' declared on type 'System.String' cannot be called with instance of type 'EmailAddress'
at System.Linq.Expressions.Expression.ValidateCallInstanceType(Type instanceType, MethodInfo method)
at System.Linq.Expressions.Expression.ValidateMethodAndGetParameters(Expression instance, MethodInfo method)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments) at HotChocolate.Data.Filters.Expressions.FilterExpressionBuilder.StartsWith(Expression property, Object value) at HotChocolate.Data.Filters.Expressions.QueryableStringStartsWithHandler.HandleOperation(QueryableFilterContext context, IFilterOperationField field, IValueNode value, Object parsedValue) at HotChocolate.Data.Filters.Expressions.QueryableOperationHandlerBase.TryHandleOperation(QueryableFilterContext context, IFilterOperationField field, ObjectFieldNode node, Expression& result) at HotChocolate.Data.Filters.FilterOperationHandler`2.TryHandleEnter(TContext context, IFilterField field, ObjectFieldNode node, ISyntaxVisitorAction& action)
at HotChocolate.Data.Filters.FilterVisitor`2.OnFieldEnter(TContext context, IFilterField field, ObjectFieldNode node) at HotChocolate.Data.Filters.FilterVisitorBase`2.Enter(ObjectFieldNode node, TContext context)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment