Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With UseParameterizedNamesInDynamicQuery, can't compare enum type with String #668

Closed
neilbgr opened this issue Feb 7, 2023 · 8 comments
Assignees
Labels

Comments

@neilbgr
Copy link
Contributor

neilbgr commented Feb 7, 2023

1. Description

When UseParameterizedNamesInDynamicQuery = true in config (for best perfs), can not compare enum type with String .

2. Project fiddle

https://dotnetfiddle.net/ZKJC6i

3. Source

// @nuget: System.Linq.Dynamic.Core
// @nuget: Z.EntityFramework.Classic

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Linq.Dynamic.Core;
					
public class Program
{	
	public static void Main()
	{
		GenerateData();
		
		var context = new EntityContext();
		
		ParsingConfig.Default.UseParameterizedNamesInDynamicQuery = false;
		
		var query1 = context.Customers			
			.Where("Gender = @0", "Female");
		query1.Dump();
					
		ParsingConfig.Default.UseParameterizedNamesInDynamicQuery = true;
		try
		{
			var query2 = context.Customers
				.Where("Gender = @0", "Female");
			query2.Dump();
		}
		catch (Exception ex)
		{
			ex.Message.Dump();
		}
			
	}
		 
	public static void GenerateData()
    {
        var list = new List<Customer>();
        list.Add(new Customer()
        {
            Name = "Terri Lee Duffy",
            CompanyName = "ABC",
            City = "Paris",
            Phone = "333-444444",
			Location = new Location() { Name = "test" },     
			LastContact = DateTimeOffset.Parse("2022-11-14"),
			Gender = Gender.Male
        });
		list.Add(new Customer()
        {
            Name = "Garry Moore",
            CompanyName = "ABC",
            City = "Paris",
            Phone = "54654-444444",
			Location = new Location() { Name = "ohter test", UpdateAt = DateTimeOffset.Parse("2022-11-16") },     
			LastContact = DateTimeOffset.Parse("2022-11-16"),
			Gender = Gender.Female				
        });

        using (var context = new EntityContext())
        {
            context.Customers.AddRange(list);
            context.BulkSaveChanges();
        }
	}
	
	public class EntityContext : DbContext
	{
		public EntityContext() : base(FiddleHelper.GetConnectionStringSqlServer())
		{
		}
		
		public DbSet<Customer> Customers { get; set; }
		public DbSet<Location> Locations { get; set; }
	}
	
	public class Customer
    {
        public int CustomerID { get; set; }
        public string Name { get; set; }
        public string CompanyName { get; set; }
        public string City { get; set; }
        public string Phone { get; set; }
		public Location Location { get; set; }
		public DateTimeOffset? LastContact { get; set; }
		public Gender Gender { get; set; }
    }
	
	public class Location
    {
        public int LocationID { get; set; }
        public string Name { get; set; }
		public DateTimeOffset UpdateAt { get; set; }
    }
	
	public enum Gender
	{
		Male = 0,
		Female = 1,
		Other = 2
	}
	
}

4. Console result

Dumping object(System.Data.Entity.Infrastructure.DbQuery`1[Customer])
[
   {
   City         : Paris
   CompanyName  : ABC
   CustomerID   : 2
   Gender       : Female
   LastContact  : 11/16/2022 00:00:00 +00:00
   Location     : null
   Name         : Garry Moore
   Phone        : 54654-444444
   }
]
Dumping object(String)
 Operator '=' incompatible with operand types 'Gender' and 'String'

5. Related issue

#645

(Sorry, me again...)

@StefH StefH self-assigned this Feb 8, 2023
@StefH StefH added the bug label Feb 8, 2023
@StefH
Copy link
Collaborator

StefH commented Feb 10, 2023

#672

@StefH
Copy link
Collaborator

StefH commented Feb 11, 2023

@neilbgr
I think it's fixed now.

Can you please verify the PR (#672).
And take a look at:
When_UseParameterizedNamesInDynamicQuery_IsTrue_WrappedStringValueEnum_Should_Be_Unwrapped

@neilbgr
Copy link
Contributor Author

neilbgr commented Feb 11, 2023

Yes! I check this now.

@neilbgr
Copy link
Contributor Author

neilbgr commented Feb 11, 2023

So, works fine with "=" operator.

But, I need also the case with "in ()" like this :

 [Fact]
    public void When_UseParameterizedNamesInDynamicQuery_IsTrue_WrappedStringValueEnums_Should_Be_Unwrapped()
    {
        // Arrange
        var list = new List<Customer>
        {
            new()
            {
                Name = "Duffy",
                GenderType = Gender.Female
            },
            new()
            {
                Name = "Garry",
                GenderType = Gender.Male
            },
            new()
            {
                Name = "Garry",
                GenderType = Gender.Other
            },
            new()
            {
                Name = "Garry",
                GenderType = Gender.Male
            }
        };

        var config = new ParsingConfig
        {
            UseParameterizedNamesInDynamicQuery = true
        };

        // Act
        var result = list.AsQueryable().Where(config, "GenderType in (\"Female\", \"Other\")").ToArray();

        // Assert
        result.Should().HaveCount(2);
    }

I see if I can contribute to solve it.

@neilbgr
Copy link
Contributor Author

neilbgr commented Feb 11, 2023

Good news 😊
I found how to fix for:

var result = list.AsQueryable().Where(config, "GenderType in (\"Female\", \"Other\")").ToArray();

Works too:

var result = list.AsQueryable().Where(config, "GenderType = 2").ToArray();

But don't works in this case:

var result = list.AsQueryable().Where(config, "GenderType in (0, 2)").ToArray();` 

I created a branch neilbgr-668-enum-string-wrapped with new tests and the fix in ExpressionParser.cs.
Will could I push to your repo for share ?

@StefH
Copy link
Collaborator

StefH commented Feb 11, 2023

You can make a pull request to my branch.

neilbgr added a commit to neilbgr/System.Linq.Dynamic.Core that referenced this issue Feb 12, 2023
@StefH
Copy link
Collaborator

StefH commented Feb 13, 2023

I did merge your branch into mine.

please review my PR

And if you have more updates, create a new branch (with different name) and make a PR to my branch.

StefH added a commit that referenced this issue Feb 14, 2023
…erator for Enum (#672)

* Fixed ExpressionParser when WrappedValue-string is used for equals-operator to compare Enum

* .

* .

* Partial fixed ExpressionParser when WrappedValue-string is used for in-operator and left operand is enum (#668)

* Fix

* .

---------

Co-authored-by: neilbgr <neilbgr@laposte.net>
@StefH
Copy link
Collaborator

StefH commented Feb 14, 2023

#672

@StefH StefH closed this as completed Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants