-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Unknown
-
Affects Version/s: 8.0.3
-
None
-
None
-
Dotnet Drivers
-
None
-
None
-
None
-
None
-
None
-
None
I have model that looks like that:
public class Notification { public Guid Id { get; set; } public required string UserId { get; set; } public List<Channel> Channels { get; set; } = []; } public class Channel { public UserNotificationMedium Medium { get; set; } public ChannelStatus Status { get; set; } public DateTimeOffset? Sent { get; set; } } public enum ChannelStatus { Pending, Sent, Failed } public enum UserNotificationMedium { Email, Push, Sms, SignalR } // Configuration for notification public class NotificationConfiguration : IEntityTypeConfiguration<Notification> { public override void Configure(EntityTypeBuilder<Notification> builder) { builder.HasKey(x => x.Id); builder.Property(x => x.UserId).IsRequired(); builder.OwnsMany(x => x.Channels, channels => { channels.Property(x => x.Medium).HasConversion<string>(); channels.Property(x => x.Status).HasConversion<string>(); }); } }
When i create new entries everything works like excepted, both enums are saved in the collection as strings. Now i want to create a query over the data filtering on those enums. I have a like of UserNotificationMedium enums and i want to filter all notifications based on their values. The query looks like this:
List<UserNotificationMedium> notificationTypes = [UserNotificationMedium.Email, UserNotificationMedium.Push]
var filteredQuery = dbContext.Notifications.Include(n => n.Channels)
.Where(n => n.UserId == userId && n.Channels.Any(c => notificationTypes.Contains(c.Medium)));
Even though i have notificaitons with channels that do have those enums - result comes back empty. I turned on the query logging and here's the result:
Executed MQL query notifications.Notifications.aggregate([{ "$match" : { "$and" : [{ "UserId" : "8ead12f5-01d1-4c96-85ae-99f6232a9c32" }, { "$expr" : { "$anyElementTrue" : { "$map" : { "input" : "$Channels", "as" : "o", "in" : { "$in" : ["$$o.Medium", [1, 3]] } } } } }] } }, { "$sort" : { "CreatedAt" : -1 } }, { "$skip" : NumberLong(0) }, { "$limit" : NumberLong(1000) }])
Here we can see that the query was translated to use enum underlying int value for filter, not the string value as expected.
Workaround for this is as follows:
var notificationTypesAsString = notificationTypes.Select(e => e.ToString()).ToList(); var filteredQuery = dbContext.Notifications.Include(n => n.Channels) .Where(n => n.UserId == userId && n.Channels.Any(c => notificationTypesAsString.Contains(c.Medium.ToString())));
Not perfect, but works for now. But i believe that the underlying issue is a bug on the MongoDB EF provider