I inserted a record via LiteDb.Shell.exe and when I try to retrieve the record in my code, it throws an InvalidCastException. If I try to find the record via the shell, I get an Unable to cast object of type 'System.Int32' to type 'System.String'.
Here's my model
public class Query
{
public int Id { get; set; }
public string FilePath { get; set; }
public string Hash { get; set; }
public string[] Arguments { get; set; }
public int[] PrintoutIds { get; set; }
}
Here's the shell command I used to insert a record
db.queries.insert {FilePath: "C:/Temp/Reporting Test.sql", Hash: "8074458BDE071C6B05A6EE1C718EC29CC92C89A2967D6E314EADEB0BA60F270E", Arguments: ["Tenant_ID"], PrintoutIds: [1]}
Here's the shell commands I used to try to get the record back
> db.queries.find
[1]: {"_id":{"$oid":"5a0ef5219996a32e14886d6b"},"FilePath":"C:/Temp/Reporting Test.sql","Hash":"8074458BDE071C6B05A6EE1C718EC29CC92C89A2967D6E314EADEB0BA60F270E","Arguments":["Tenant_ID"],"PrintoutIds":[1]}
> db.queries.find PrintoutIds contains 1
Unable to cast object of type 'System.Int32' to type 'System.String'.
> db.queries.find PrintoutIds contains "1"
> db.queries.find $.PrintoutIds[*] contains 1
Unable to cast object of type 'System.Int32' to type 'System.String'.
> db.queries.find $.PrintoutIds[*] contains "1"
Here's the code I'm using to retrieve the record
public IEnumerable<dynamic> DoStuffWithAQuery(int id)
{
using (var reportDatabase = new LiteDatabase("C:/Stuff/Database/Reporting/Reports.db"))
{
var queryCollection = reportDatabase.GetCollection<Query>("queries");
queryCollection.EnsureIndex(x => x.PrintoutIds, "$.PrintoutIds[*]");
Query query;
try
{
// The next line throws an InvalidCastException.
query = queryCollection.Find(x => x.PrintoutIds.Contains(id)).Single();
}
catch (InvalidOperationException)
{
throw new WebFaultException<string>("Only one query can be mapped to a printout",
HttpStatusCode.BadRequest);
}
return DoSomeStuff(query);
}
}
Here's the full stacktrace I get
The server encountered an error processing the request. The exception message is 'Specified cast is not valid.'. See server logs for more details. The exception stack trace is:
at
lambda_method(Closure , Object , Object ) at
LiteDB.BsonMapper.DeserializeObject(Type type, Object obj, BsonDocument value) at
LiteDB.BsonMapper.Deserialize(Type type, BsonValue value) at
LiteDB.BsonMapper.ToObject(Type type, BsonDocument doc) at
LiteDB.BsonMapper.ToObject[T](BsonDocument doc) at
LiteDB.LiteCollection`1.<Find>d__17.MoveNext() at
System.Linq.Enumerable.Single[TSource](IEnumerable`1 source) at
ReportService.DoStuffWithAQuery(String tenantName, Int32 id, Object parameters) in C:\C# Workspace\MyProject\ReportService.cs:line 35 at
SyncInvokeDoStuffWithAQuery(Object , Object[] , Object[] ) at
System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
There are 2 thinks here
First, if your strong class use _id as an integer, you can't use shell with ObjectId (deafault). Try:
db.queries.insert { ... } id:intNow, your document will be insert with auto-id as
Int32(_id: 1). This will avoid your mapper error here:query = queryCollection.Find(x => x.PrintoutIds.Contains(id)).Single();Second, it about "contains" keyword. In shell, "contains" works as
String.Contains. Shell useQuery.Contains(string field, string text). So, you can't pass an Int as "text".Your query, in shell, must use
=With no index
Or, create an index
Now, using indexName
But..... when you are writing Linq expressions,
Containscan be fromStringor fromIEnumerable. If are fromString, works as normalQuery.Contains, but if are from anIEnumerable, works withQuery.EQ.