I’m trying to figure-out the simplest way to persist a complex(2 level deep) object as this one
public class Root
{
[AutoIncrement]
public int RootId { get; set; }
[ServiceStack.DataAnnotations.Reference]
public List<Item> Items { get; set; }
}
public class Item
{
[AutoIncrement]
public int ItemId { get; set; }
public int RootId { get; set; } //`{Parent}Id` convention to refer to Client
public string MyValue { get; set; }
}
That what I’d like to accomplish
int rootId = 0;
var root = new Root { Items = new List<Item> { new Item { MyValue = "x" } } };
using (var db = _dbConnectionFactory.Open(_namedConnectionString))
{
db.Store(root, references: true);
}
root.RootId.Should().BeGreaterThan(0);// from autoincrement column
root.Items.First().ItemId.Should().BeGreaterThan(0);// from autoincrement column
rootId = root.RootId;
// disconnected scenario
var root2 = new Root { RootId = rootId, Items = new List<Item> { new Item { RootId = rootId, MyValue = "y" }, new Item { RootId = rootId, MyValue = "z" } } };
using (var db = _dbConnectionFactory.Open(_namedConnectionString))
{
db.Store(root, references: true);
}
root.Items.Should().HaveCount(2); // MyValue = "x" should be been deleted
root.Items.Count(x => x.MyValue == "y").Should().Be(1);
root.Items.Count(x => x.MyValue == "z").Should().Be(1);
In other world I’d like to avoid to handle the ItemId, have all my existing Items deleted and have the new items added (of course with a new ItemId): I do not want to have to explicitly delete the existing items but those should be automatically deleted since the new graph does not contain the old one. The store method should figure out what has to be deleted, what has to be added and what to be updated only according to the foreign key.
Save doesn’t delete non-existing references, it only inserts or updates existing ones. IMO it’s a dangerous default to delete missing references as it’d need to ensure the POCO is always fully populated. It may make sense to be an opt-in option, e.g:
Ok thanks, understood.
Still one doubt… If I do not use the property with the AutoIncrement attribute within the Item class, the add/insert not happened while a simple update of a single item will be executed… why? I was expecting same behaviour regardless the AutoIncrement property within the POCO: the FK property should be enough, isn’t it?
The convention for the Primary Key field is just Id e.g:
public class Root
{
public int Id { get; set; }
[Reference]
public List<Item> Items { get; set; }
}
public class Item
{
public int Id { get; set; }
public int RootId { get; set; }
public string MyValue { get; set; }
}
If you don’t want to use the default conventions you need to annotate Primary Key Attributes with [PrimaryKey].
Thanks for the carification, but that was not my point: I’d like to do not have at all the PK property in the POCO class (the child item).
public class Item
{
public int RootId { get; set; }
public string MyValue { get; set; }
}
but If do not add that property to the POCO class, the ORM engine executes a single update (calling Store after the first insert) although the Items property contains more than one Item