Search code examples
c#.netmongodbmongodb-.net-driver

MongoDB Unable to determine the serialization information for the expression error


My data is having following structure

public enum ParamType
{
    Integer=1,
    String=2,
    Boolean=3,
    Double=4
}

public class Gateway
{
    public int _id { get; set; }
    public string SerialNumber { get; set; }
    public List<Device> Devices { get; set; }
}

public class Device
{        
    public string DeviceName { get; set; }
    public List<Parameter> Parameters { get; set; }
}

public class Parameter
{
    public string ParamName { get; set; }
    public ParamType ParamType { get; set; }
    public string Value { get; set; }
}

I filled 10 document objects of Gateway in a MongoDB database. Now I want to query all those gateways which contains a device having Parameter with ParamName as "Target Temperature" and whose Value > 15.

I created following queries

var parameterQuery = Query.And(Query<Parameter>.EQ(p => p.ParamName, "Target Temperature"), Query<Parameter>.GT(p => int.Parse(p.Value), 15));

var deviceQuery = Query<Device>.ElemMatch(d => d.Parameters, builder => parameterQuery);

var finalQuery = Query<Gateway>.ElemMatch(g => g.Devices, builder => deviceQuery);

But when I run this, it is giving an exception

Unable to determine the serialization information for the expression: (Parameter p) => Int32.Parse(p.Value)

Please suggest where I am wrong.


Solution

  • As the error suggests, you can't use Int32.Parse inside your query. This lambda expression is used to get out the name of the property and it doesn't understand what Int32.Parse is.

    If you are querying a string, you need to use a string value for comparison:

    var parameterQuery = Query.And(Query<Parameter>.EQ(p => p.ParamName, "Target Temperature"), Query<Parameter>.GT(p => p.Value, "15"));
    

    However, that's probably not what you want to do since you're using GT. To be treated as a number for this comparison you need the value to actually be an int in mongo, so you would need to change the type of your property:

    public class Parameter
    {
        public string ParamName { get; set; }
        public ParamType ParamType { get; set; }
        public int Value { get; set; }
    }
    
    var parameterQuery = Query.And(Query<Parameter>.EQ(p => p.ParamName, "Target Temperature"), Query<Parameter>.GT(p => p.Value, 15));