Not sure is it bug or feature but it looks unexpected to me:
Console output:
Kristian[2]
0 = Rex
1 = Тузик
Kristian[3]
0 = Rex
1 = Тузик
1 = Тузик
public class Person : RealmObject
{
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
public IList<Dog> Dogs { get; }
}
public class Dog : RealmObject
{
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
}
and usage:
var realm = Realm.GetInstance();
realm.Write(() => realm.RemoveAll());
var dog1 = new Dog
{
Id = 0,
Name = "Rex"
};
var dog2 = new Dog
{
Id = 1,
Name = "Bethoven"
};
Person k = new Person
{
Id = 1,
Name = "Kristian",
Dogs = { dog1, dog2 }
};
realm.Write(() => realm.Add(k));
var dog3 = new Dog
{
Id = 1,
Name = "Тузик"
};
realm.Write(() =>
{
realm.Add(dog3, true);
k.Dogs.Add(dog3);
});
Console.WriteLine($"{k.Name}[{k.Dogs.Count}]");
foreach (var dog in k.Dogs)
Console.WriteLine($"{dog.Id} = {dog.Name}");
Realm: 4.2.0
Related:
If one adds the same object to the inner collection then count of objects will be increases as well.
That's expected - a list can hold multiple references to the same object. realm.All<Dog>().Count() should still be 2, however.
yeah, thank you.
Closing issue since this is not a bug. Though I still think it will be nice to document it explicitly.
Just curious: how one can remove all "duplicate" references?
The same way you would with any other IList<T> implementation:
while (list.Contains(item))
{
list.Remove(item);
}
For what it's worth, I think the behavior you expect here is that of a Set<T>. While lists in Realm do not have set semantics, we're considering adding a Set datatype which models to-many relationships with set semantics.
awesome, thank you
You could also model set semantics using the inverse relationships feature.
Thank you. I was suggested that already but I'm still unsure how to apply it.
Something like that?
public class Dog : RealmObject
{
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
[Backlink(nameof(Person.Dogs))]
public IQueryable<Person> Owner { get; }
}
and usage:
var dogs = realm.All<Dog>().ToArray().Where(d => d.Owner.First().Id == k.Id);
The model would look something like:
public class Dog : RealmObject
{
public Person Owner { get; set; }
}
public class Person : RealmObject
{
[Backlink(nameof(Dog.Owner))]
public IQueryable<Dog> Dogs { get; }
}
So if you have a person var myPerson = realm.All<Person>().FirstOrDefault(p => p.Id == 123), then the myPerson.Dogs collection will contain exactly one entry for each dog that has dog.Owner == myPerson.
Most helpful comment
For what it's worth, I think the behavior you expect here is that of a
Set<T>. While lists in Realm do not have set semantics, we're considering adding a Set datatype which models to-many relationships with set semantics.