1

I have a class that has multiple fields. Lets say for example:

class MyClass {
    public int x {get; set;}
    public int y {get; set;}
    public int z {get; set;}
}

I want to use LiteDB with that class, and have it use both x and y as a key. So for example:

MyClass{x: 0, y: 0, z:0}
MyClass{x: 0, y: 1, z:0}

Will be considered as 2 different entries in my LiteDB database.

So I basically want something like this:

var mapper = BsonMapper.Global;
mapper
    .Entity<MyClass>()
    .Id(c => new {c.x, c.y});
var db = new LiteDatabase("PATH_HERE", mapper);

Obviously, Id(c => new {c.x, c.y}); doesnt work. I've also tried

.Id(c => c.x)
.Id(c => c.y);

But it doesn't work either. I've tried looking for a solution in the LiteDB documentation, but was unable to find anything. Is this possible? If so, I would love to understand how to achieve my goal.

Thanks!

Ungoliant
  • 133
  • 2
  • 14

1 Answers1

3

In BsonDocument, _id must be a single value, there is no compound key. But this value can be another document. So, you can use this:

class MyId {
    public int x { get; set; }
    public int y { get; set; }
}

class MyClass {
    public MyId Id { get; set; }
    public int y { get; set; }
}

Now you can find using

col.Find(x => x.Id = new Id { x = 0, y = 1 })
mbdavid
  • 1,076
  • 7
  • 8
  • Thanks. I hoped to avoid editing MyClass. Also, some info that was supposed to be stored in the key, the MyClass instance was supposed to be unaware of. I ended up using a new field key, and searching by rest of the fields. – Ungoliant Jan 03 '18 at 14:24
  • So `.FindById()` would not be used in this circumstance? and the `.Find(predicate)` version automatically uses the PK index? – controlbox Aug 31 '18 at 09:19
  • 1
    `FindById` requires `BsonValue` and there is no direct conversion from your class to `BsonValue`. To use find by id, you must use bsonmapper too: `FindById(mapper.ToDocument(new Id { x = 0, y = 1 }))` – mbdavid Sep 03 '18 at 16:52