LinkingSetRelation Explanation by jsbUSMC

lquantz edited this page Oct 16, 2016 · 3 revisions
Clone this wiki locally

Thanks to jsbUSMC for this explanation in the issue #309 of the Serenity.

I copy it in the Wiki for a better consultation.


The [LinkingSetRelation(typeof(EntityRow), "field1", "field2")] attribute is used when you are adding multiple selection to a dropdown list. So, when you define the [LookupEditor(typeof(EntityXRow), Multiple = true), ClientSide] attribute on a field to have a dropdown list with multiple selection enabled, you need to also place a [LinkingSetRelation] attribute on it as well to define the relationship between the field and the selection choices. In the case of the example you're seeing in Northwind, there are multiple selections available for customer representatives, meaning that one customer can have multiple employees assigned to that client. Here, the [LookupEditor(typeof(EmployeeRow), Multiple = true), ClientSide] informs us that the LookupEditor is going to populate with entities from the EmployeeRow and that multiple selection is enabled. The [LinkingSetRelation(typeof(CustomerRepresentativesRow), "CustomerId", "EmployeeId")] attribute informs us that each of the selections of employees is going associate with a specific customer, and those fields are located in the CustomerRepresentativesRow class. When you check the CustomerRepresentativesRow.cs class, you'll see this:

    // ....
    public sealed class CustomerRepresentativesRow : Row, IIdRow
    {
        [DisplayName("Representative Id"), Column("RepresentativeID"), Identity]
        public Int32? RepresentativeId
        {
            get { return Fields.RepresentativeId[this]; }
            set { Fields.RepresentativeId[this] = value; }
        }

        [DisplayName("Customer Id"), Column("CustomerID"), NotNull]
        public Int32? CustomerId
        {
            get { return Fields.CustomerId[this]; }
            set { Fields.CustomerId[this] = value; }
        }

        [DisplayName("Employee Id"), Column("EmployeeID"), NotNull]
        public Int32? EmployeeId
        {
            get { return Fields.EmployeeId[this]; }
            set { Fields.EmployeeId[this] = value; }
        }

    // .....
    }

What's happening behind the scenes is for every employee you select from the dropdown list, when saved Serenity is going to create a new row in the CustomerRepresentatives table in the db, with a unique RepresentativeId, and the CustomerId from the Customer class along with the EmployeeId from the Employee class in their respective fields.

These attributes must be placed on a List field in your EntityRow class, and in your RowFields class you have to define that field as:

    public CustomClassField<List<Int32>> FieldName;

In the case here, involving the Customer Representatives and Employee classes, the entry in RowFields is simply:

    public ListField<Int32> Representatives;

I hope this helps clear up some confusion for you.