Getting error : The binary operator Equal is not defined for the types 'System.Guid' and 'System.String'

c# entity-framework expression-trees

Question

My Expression Class is Here

        public static class ExpressionBuilder
    {
        private static MethodInfo containsMethod = typeof(string).GetMethod("Contains");
        private static MethodInfo startsWithMethod = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
        private static MethodInfo endsWithMethod = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });


        public static Expression<Func<T,
        bool>> GetExpression<T>(IList<Filter> filters)
        {
            if (filters.Count == 0)
                return null;

            ParameterExpression param = Expression.Parameter(typeof(T), "t");
            Expression exp = null;

            if (filters.Count == 1)
                exp = GetExpression<T>(param, filters[0]);
            else if (filters.Count == 2)
                exp = GetExpression<T>(param, filters[0], filters[1]);
            else
            {
                while (filters.Count > 0)
                {
                    var f1 = filters[0];
                    var f2 = filters[1];

                    if (exp == null)
                        exp = GetExpression<T>(param, filters[0], filters[1]);
                    else
                        exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0], filters[1]));

                    filters.Remove(f1);
                    filters.Remove(f2);

                    if (filters.Count == 1)
                    {
                        exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0]));
                        filters.RemoveAt(0);
                    }
                }
            }

            return Expression.Lambda<Func<T, bool>>(exp, param);
        }

        private static Expression GetExpression<T>(ParameterExpression param, Filter filter)
        {
            MemberExpression member = Expression.Property(param, filter.PropertyName);
            ConstantExpression constant = Expression.Constant(filter.Value);

            switch (filter.Operation)
            {
                case Op.Equals:
                    return Expression.Equal(member, Expression.Call(Expression.Convert(Expression.Constant(search.RetrieveGuid), typeof(object)), typeof(object).GetMethod("ToString"))), constant);

                case Op.GreaterThan:
                    return Expression.GreaterThan(member, constant);

                case Op.GreaterThanOrEqual:
                    return Expression.GreaterThanOrEqual(member, constant);

                case Op.LessThan:
                    return Expression.LessThan(member, constant);

                case Op.LessThanOrEqual:
                    return Expression.LessThanOrEqual(member, constant);

                case Op.Contains:
                    return Expression.Call(member, containsMethod, constant);

                case Op.StartsWith:
                    return Expression.Call(member, startsWithMethod, constant);

                case Op.EndsWith:
                    return Expression.Call(member, endsWithMethod, constant);
            }

            return null;
        }

        private static BinaryExpression GetExpression<T>
        (ParameterExpression param, Filter filter1, Filter filter2)
        {
            Expression bin1 = GetExpression<T>(param, filter1);
            Expression bin2 = GetExpression<T>(param, filter2);

            return Expression.AndAlso(bin1, bin2);
        }
    }

when I use this code to construct an expression

 delegExpFilters = EntityExpression.ExpressionBuilder.GetExpression<Contact>(domainFilter).Compile();

my sphere A list of records with the property field name, operator, and value is included in the filter, and my field is GUID.

GetExpression throws me an error when I call it. System.Guid and System.String are not specified types for the binary operator Equal.

1
5
3/13/2017 4:46:13 PM

Accepted Answer

The filter value, which is a string, is not being converted to the proper type:

ConstantExpression constant = Expression.Constant(filter.Value);

Consider you have an integer property filter calledAmount :

var filter = new Filter {
   PropertyName = "Amount",
   Operation = Op.GreaterThan,
   Value = "42"
};

Your program will produce an expression that is the same as the following code.

contract.Amount > "42"

Such an integer to string comparison is not permitted.


Obtain the property type, then transform the filter value to that type. the following steps:

  1. Convert types for properties.
  2. Examine its ability to transform strings to property types.
  3. Convert (which will provide the property value asobject
  4. Create a cast expression to change the value of a property fromobject kind of property

Here is a sample ofGetExpression method

var member = Expression.Property(param, filter.PropertyName);
var propertyType = ((PropertyInfo)member.Member).PropertyType;
var converter = TypeDescriptor.GetConverter(propertyType); // 1

if (!converter.CanConvertFrom(typeof(string))) // 2
   throw new NotSupportedException();

var propertyValue = converter.ConvertFromInvariantString(filter.Value); // 3
var constant = Expression.Constant(propertyValue);
var valueExpression = Expression.Convert(constant, propertyType); // 4

In binary expressions that you are returning, you need to utilize this value expression rather than your constant expression. E.g.:

case Op.LessThan:
    return Expression.LessThan(member, valueExpression);
case Op.Equal:
    return Expression.Equal(member, valueExpression);
// etc

You should also use binary expression for equality. Finally, look forAmount it will be converted to

 contract.Amount > (int)42
13
3/13/2017 4:45:48 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow