mbdavid / LiteDB

LiteDB - A .NET NoSQL Document Store in a single data file
http://www.litedb.org
MIT License
8.62k stars 1.25k forks source link

NullReferenceException on newly created collection #1315

Open sekulicb opened 5 years ago

sekulicb commented 5 years ago

Hi. I noticed that when you call GetCollection method for some entity, and if that collection does not exist, it should create a new one. However if you call Count() down the line to check are there any elements at all, LiteDb throws NullReferenceException. This is the part of stack trace:

at LiteDB.StreamExtensions.<>c__DisplayClass4_0.b__0() at LiteDB.FileHelper.TryExec(Action action, TimeSpan timeout) at LiteDB.StreamExtensions.TryLock(FileStream stream, Int64 position, Int64 length, TimeSpan timeout) at LiteDB.FileDiskService.Lock(LockState state, TimeSpan timeout) at LiteDB.LockService.Read() at LiteDB.LiteEngine.Count(String collection, Query query) at LiteDB.LiteCollection`1.Count()

If GetCollection will create new collection, I see no reason why LiteCollection.Count() should throw such exception ?

LiteDB version 4.1.4 .NET framework 4.7.2

JensSchadron commented 5 years ago

Hi @sekulicb,

LiteCollection.Count() seems to work just fine using the following code.

using (var db = new LiteDatabase(new MemoryStream()))
{
    var table = db.GetCollection<TestClassIssue1315>();

    var count = table.Count();

    Debugger.Break();
}

Might it be possible that the issue exists somewhere else in your code? Could you maybe provide us with a code snippet that reproduces this error?

sekulicb commented 5 years ago

Hi @JensSchadron

This is my example:

public SettingsEntity GetSettingsByUsername(string username)
{
            using (var db = _repositoryFactory.GetDatabase())
            {
                var settings = db.GetCollection<SettingsEntity>(DbEntity.Settings.AsString());

                var userSettings = settings.FindOne(s => s.Username.Equals(username));

                if (settings.Count() == 0 || userSettings == null)
                {
                    var defaultSettings = JsonReader.LoadSettings();
                    defaultSettings.Username = username;

                    return defaultSettings;
                }

                return userSettings;
            }
}

Where _repositoryFactory.GetDatabase() just returns LiteDatabase obj with connection string from config file.

I forgot to mention that I use Count() to check if sum of elements is equal to zero.

Thanks.