bendytree
bendytree

Reputation: 13609

Circular References in RavenDB

I'm using RavenDB with models like:

public class Cart {
    List<Item> Items = new List<Item>();
}

public class Item {
    public Cart Cart;
}

When I add an Item to a Cart, I wire up both sides of the relationship.

How does RavenDB handle serializing & deserializing this? Will the reference to Cart be assigned automatically or is there a way to manually wire it on load?

Upvotes: 5

Views: 1436

Answers (2)

bendytree
bendytree

Reputation: 13609

If you save cart you will get an exception 'Self referencing loop detected...' when you call SaveChanges().

The fix is easy. You add the [JsonObject(IsReference = true)] attribute to Cart. This tells the serializer to store Item's Cart as a reference instead of as a new object.

[JsonObject(IsReference = true)] 
public class Cart
{
    public List<Item> Items = new List<Item>();
}

public class Item
{
    public Cart Cart;
}

I also wanted to mention that it IS property deserialized. In other words, Cart is re-assigned to Item when it is loaded.

var cart = new Cart();
cart.Items.Add(new Item { Cart = cart });
session.Store(cart);
session.SaveChanges();

...

var cart = session.Query<Cart>().First();
Assert.ReferenceEquals(cart, cart.Items.First().Cart); //this works

Upvotes: 9

Ayende Rahien
Ayende Rahien

Reputation: 22956

You probably want to read this to get a handle on how RavenDB works in those scenarios: http://ravendb.net/docs/theory/document-structure-design

In this case, Item & Card would actually be serialized into the SAME document, which is likely not what you want. References in RavenDB should include just the id of the references document, not the document itself.

Upvotes: 0

Related Questions