LINQ query ignores enum type conversion

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Unknown
    • 8.1.1
    • 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

            Assignee:
            Damien Guard
            Reporter:
            Jakub Syty
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: