diff --git a/src/LinqTests/Bugs/Bug_3610_enum_array_as_string_in_compiled_query.cs b/src/LinqTests/Bugs/Bug_3610_enum_array_as_string_in_compiled_query.cs new file mode 100644 index 0000000000..00d66300cd --- /dev/null +++ b/src/LinqTests/Bugs/Bug_3610_enum_array_as_string_in_compiled_query.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Marten; +using Marten.Linq; +using Marten.Testing.Harness; +using Shouldly; +using Weasel.Core; + +namespace LinqTests.Bugs; + +public class Bug_3610_enum_array_as_string_in_compiled_query : BugIntegrationContext +{ + [Fact] + public async Task use_the_query() + { + StoreOptions(opts => + { + opts.UseNewtonsoftForSerialization(enumStorage: EnumStorage.AsString, + nonPublicMembersStorage: NonPublicMembersStorage.NonPublicSetters); + }); + + var elayne = new Foo { Name = "Elayne", Status = StatusEnum.Active }; + theSession.Store(elayne); + await theSession.SaveChangesAsync(); + + var results = await theSession.QueryAsync(new ActiveFooQuery("Elayne")); + + results.Any().ShouldBeTrue(); + } +} + +public class ActiveFooQuery : ICompiledListQuery, IQueryPlanning +{ + public string Name { get; set; } + public ActiveFooQuery() + { + + } + + public ActiveFooQuery(string name) + { + Name = name; + } + + public Expression, IEnumerable>> QueryIs() => + q => q.Where(x => x.Status.In(StatusEnum.Active) && x.Name == Name); + + public void SetUniqueValuesForQueryPlanning() + { + Name = "ActiveFooQuery"; + } +} + +public class Foo +{ + public Guid Id { get; set; } + public StatusEnum Status { get; set; } + public string Name { get; set; } +} + +public enum StatusEnum +{ + Active, + Inactive +} diff --git a/src/Marten/Internal/CompiledQueries/ParameterUsage.cs b/src/Marten/Internal/CompiledQueries/ParameterUsage.cs index a0e331cebd..0328f6a785 100644 --- a/src/Marten/Internal/CompiledQueries/ParameterUsage.cs +++ b/src/Marten/Internal/CompiledQueries/ParameterUsage.cs @@ -63,8 +63,25 @@ public void GenerateCode(GeneratedMethod method, string parametersVariableName, else { method.Frames.Code($"{parametersVariableName}[{Index}].Value = {{0}};", Constant.For(Parameter.Value)); - method.Frames.Code($"{parametersVariableName}[{Index}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {typeof(NpgsqlDbType).FullNameInCode()}.{Parameter.NpgsqlDbType};"); + + method.Frames.Code($"{parametersVariableName}[{Index}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {npgsqlDataTypeInCodeFor(Parameter)};"); + } + } + + // Hack for part of GH-3610 + private static string npgsqlDataTypeInCodeFor(NpgsqlParameter parameter) + { + if (parameter.Value is string[]) + { + return $"{typeof(NpgsqlDbType).FullNameInCode()}.{NpgsqlDbType.Array} | {typeof(NpgsqlDbType).FullNameInCode()}.{NpgsqlDbType.Varchar}"; } + + if (parameter.Value is int[]) + { + return $"{typeof(NpgsqlDbType).FullNameInCode()}.{NpgsqlDbType.Array} | {typeof(NpgsqlDbType).FullNameInCode()}.{NpgsqlDbType.Integer}"; + } + + return $"{typeof(NpgsqlDbType).FullNameInCode()}.{parameter.NpgsqlDbType}"; } private void generateSimpleCode(GeneratedMethod method, MemberInfo member, Type memberType, diff --git a/src/Marten/Marten.csproj b/src/Marten/Marten.csproj index c73309a7a5..2c468cf8e1 100644 --- a/src/Marten/Marten.csproj +++ b/src/Marten/Marten.csproj @@ -50,8 +50,8 @@ - - + +