WCF RIA Services and DTO with association

This post will be short, I notice that some people are asking about how to send an object graph which will include an association to other objects. First of all, be careful with the distribution of an object graph, wrong design can affect performance in a way that to much data is passed over the wire.

Here is an simple Order class, this class has OrderRows:

public class Order
{
    [Key]
    public int OrderID { get; set; }

    public IEnumerable<OrderRow> Rows { get; set; }
}


public class OrderRow
{
    public int OrderID { get; set; }

    [Key]
    public int OrderRowID { get; set; }

    public string Name { get; set; }
}


Here is my DomainService where I have specified a query method for the Orders:

[EnableClientAccess()]
public class DomainService1 : DomainService
{
        public IEnumerable<Order> GetOrders()
        {
            return new List<Order>()
                        {
                            new Order()
                            {
                                OrderID = 0,
                                Rows = new List<OrderRow>()
                                        {
                                            new OrderRow() { OrderID = 0, Name = "Row 0", OrderRowID = 0 },
                                            new OrderRow() { OrderID = 0, Name = "Row 1", OrderRowID = 1 }
                                        }
                            },
                                                        new Order()
                            {
                                OrderID = 1,
                                Rows = new List<OrderRow>()
                                        {
                                            new OrderRow() { OrderID = 1, Name = "Row 0", OrderRowID = 0 },
                                            new OrderRow() { OrderID = 1, Name = "Row 1", OrderRowID = 1 }
                                        }
                            }

                        };
        }
}

Note: I just fake the loading of data in the GetOrder query method, normally I should of course use Entity Framework 4.0, nHibernate or other ORM.

If we now load the Orders from the client, the Order object we will get will not include the Rows property of the order. So the association will not be passed with the Order object. To include an association we need to add the IncludeAttribute, and also the AssociationAttribute:

public class Order
{
        [Key]
        public int OrderID { get; set; }

        [Include]
        [Association("Order_OrderRows", "OrderID", "OrderID")]
        public IEnumerable<OrderRow> Rows { get; set; }
}


The AssociationAttribute  is needed to specify the association between the Order and the OrderRows. The first argument is only a name of the association, the second is the main key, in this case the Order’s OrderID key, the last argument is the associated objects key which holds the value of the Order’s OrderID, in this case the OrderRow’s OrderID. The Include attributes make sure the Rows property will be included when the object is passed to the client. I hope some of you find this post useful.

If you want to know when I publish some new posts, or just follow my life, you can find med on twitter: http://www.twitter.com/fredrikn

4 Comments

  • I think it's scary when the framework forces us to have get; set; on every property, we can't protect the data inside our objects.
    And for example having get; set; on collections could lead to bugs that could be hard to find.

    I think this is a big problem for silverlight and a big step back there we handle data as they were datarows in a datatable, when we really wants to use encapsulation on our objects to be able to work with a more object oriented approach.


  • @Niclas Pehrsson:
    You can do that now, or sort of doing it.. I will short publish a blog post about it.

  • Since the move to WCF, are associations required - or can just datacontract/datamember attributes be used ?

  • i've tried in Visual Basic but i'm not able to find tyag, only .
    And my Rows collection is empty!

    Namespace Datasphere
    Namespace DTO
    Partial Public Class Impiegato

    Public Property Matricola As Int64
    Public Property Cognome As String
    Public Property Nome As String
    Public Property Dipartimento As Int16


    Public Property AssetsAssegnati As IEnumerable(Of AssetBase)

    Public Sub New()
    End Sub

    End Class

    Partial Public Class AssetBase

    Public Property Codice As Int64
    Public Property Descrizione As String
    Public Property Tipologia As Int16

    Public Sub New()
    End Sub
    End Class
    End Namespace

Comments have been disabled for this content.