db.Execute("select $ into mycollection from $file('myfile.json')")
however my json is not in a file on disc, it is in memory. This used to work:
db.Engine.Insert("mycol", JsonSerializer.Deserialize(json).AsArray.ToArray());
There does not seem to be accessibility to the Engine from LiteDatabase anymore.
Recommendation
Single instance (second option) is much faster than multi instances. In multi instances environment, each instance must do expensive data file operations: open, lock, unlock, read, close. Also, each instance has its own cache control and, if used only for a single operation, will discard all cached pages on close of datafile. In single instance, all pages in cache are shared between all read threads.
Does this mean for a web app I should be using the litedbrepo as a singleton?
BsonProperty
if you want
LiteDatabase
is the recommended way to use LiteDB.
btw,
BsonMapper.Global.RegisterType<LogEventLevel>(
serialize: (lvl) => (int)lvl,
deserialize: (bson) => (LogEventLevel)bson.AsInt32);
I am trying to store an enum as an int and getting back the enum when deserializing.
this is my mapping method, however, the string representation is stored and I get a null object reference when I try to fetch it:var results = context.LiteRepository.Fetch<LogMessage>(Query.EQ("Level", "Error"));
thanks that works! but now I get a null object reference when I try to fetch the items, it seems my mapping for the DbRef is causing the error:+ TargetSite {System.Object Deserialize(System.Type, LiteDB.BsonValue)} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
BsonMapper.Global.Entity<LogMessage>()
.Id(x => x.Id)
.DbRef(x => x.User, nameof(User));
var results = context.LiteRepository.Fetch<LogMessage>(Query.EQ("Level", (int)LogEventLevel.Error));
Do I need to do an .include?
LiteCollection<T>
. For example, if you have two classes Customer
and Product
, you would open two distinct collections: var customerCol = db.GetCollection<Customer>();
and var productCol = db.GetCollection<Product>();
LiteRepository
. Internally, it still uses distinct collections, but you can simply throw all your objects at it and it will handle the collections itself.
Product
inside Customer
. LiteDB will store Product
as a sub-document inside Customer
, so they'll both be stored in the Customer
collection. By using DbRef, you can store instances of Product
in its own collection and store only a reference to it in every customer. This, however, should not be used with LiteRepository
.
DbRef
allows you to override this behavior, but it changes the "expected" collection structure. If you want to use LiteRepository
, you should let it decide on the correct way to store things.
How does the LiteDb IQueryable Skip work with Limit?
If I have 50 entries. and I have a query like:
UserGenerator userGenerator = new UserGenerator();
while (count <= 10)
{
User newUser = userGenerator.Generate();
newUser.Name = "test";
context.LiteRepository.Insert(newUser);
count++;
testing.Add(newUser);
}
var user = context.LiteRepository.FirstOrDefault<User>(x => x.Name == "test");
var users = context.LiteRepository.Query<User>().Where(x => x.Name == "test").Skip(1).Limit(5).ToList();
The first query gives me a user with Id = 9, the second query gives me users with ids from 6 to 11.
Is my query syntax incorrect?
Newtonsoft.Json.JsonSerializationException: Error getting value from 'AsDateTime' on 'LiteDB.BsonValue'.
---> System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.DateTime'.
at lambda_method(Closure , Object )
Getting this issue with this class when serializing:
internal async Task<IEnumerable<LogMessage>> ProcessLogEvents(IEnumerable<LogEvent> logEvents, int clientId)
{
List<LogMessage> messages = new List<LogMessage>();
foreach (var evt in logEvents)
{
var logMessage = new LogMessage()
{
Level = evt.Level,
Message = evt.RenderMessage(),
TimeStamp = evt.Timestamp,
UserId = clientId
};
if (evt.Exception != null)
{
logMessage.Exception = evt.Exception.ToString();
}
if (evt.Properties.Any())
{
string complete = await Task.Run(() => Newtonsoft.Json.JsonConvert.SerializeObject(evt.Properties));
logMessage.Properties = LiteDB.JsonSerializer.Deserialize(complete).AsDocument;
}
messages.Add(logMessage);
}
return messages;
}
Converting the log events into the model for storage
//retrieval
return _repository.Query<T>()
.OrderBy(x => x.Id, order: Query.Descending)
.Where(predicate)
.Skip(skip)
.Limit(take)
.ToList();
return Ok(results);
LogEvent.Properties
with NewtonSoft.Json and serializing it right after with LiteDB.JsonSerializer, there's probably some form of incompatibility (I believe Newtonsoft serializes dates as strings, while LiteDB serializes them to a custom document)