MongoDB Unable to determine the serialization information for the expression error

匿名 (未验证) 提交于 2019-12-03 10:24:21

问题:

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.

回答1:

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)); 


回答2:

Summary

I ran into this when I was modifying a list. It appears that Linq First/FirstOrDefault was not handled well by MongoDB for me. I changed to be an array index var update = Builders<Movie>.Update.Set(movie => movie.Movies[0].MovieName, "Star Wars: A New Hope"); Note: This is in Asp.Net 5 using MongoDB.Driver 2.2.0.

Full Example

public static void TypedUpdateExample() {   var client = new MongoClient("mongodb://localhost:27017");   var database = client.GetDatabase("test");    var collection = database.GetCollection<Movie>("samples");    //Create some sample data   var movies = new Movie {     Name = "TJ",     Movies = new List<MovieData>     {       new MovieData {         MovieName = "Star Wars: The force awakens"       }     }   };    collection.InsertOne(movies);    //create a filter to retreive the sample data   var filter = Builders<Movie>.Filter.Eq("_id", movies.Id);    //var update = Builders<Movie>.Update.Set("name", "A Different Name");   //TODO:LP:TSTUDE:Check for empty movies   var update = Builders<Movie>.Update.Set(movie => movie.Movies[0].MovieName, "Star Wars: A New Hope");   collection.UpdateOne(filter, update); }  public class Movie {   [BsonId]   public ObjectId Id { get; set; }    public string Name { get; set; }    public List<MovieData> Movies { get; set; } }  public class MovieData {   [BsonId]   public ObjectId Id { get; set; }    public string MovieName { get; set; } } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!