I've been struggling for a while with many-to-many associations in a breeze app. I have issues both on the client and server side but for now, I'll just expose my client-side issue. I don't know if the approach I've come up with is correct or not, and I would really like to get feedback from the breeze team on this:
My business model:
public class Request
{
public virtual IList<RequestContact> RequestContacts { get; set; }
}
public class RequestContact
{
public virtual Contact Contact { get; set; }
public virtual Guid ContactId { get; set; }
public virtual Request Request { get; set; }
public virtual Guid RequestId { get; set; }
}
public class Contact
{
public virtual Client Client { get; set; }
public virtual Guid? ClientId { get; set; }
public virtual string Username { get; set; }
}
In the success callback of my getRequest query, I add a contacts
property to the Request and I populate it :
request.contacts = [];
request.requestContacts.forEach(function (reqContact) {
request.contacts.push(reqContact.contact);
});
The view is bound to a contacts array, defined in the controller:
<select ng-multiple="true" multiple class="multiselect" data-placeholder="Select Contacts" ng-change="updateBreezeContacts()" ng-model="request.contacts" ng-options="c as c.username for c in contacts | filter:{clientId: request.client.id} track by c.id"></select>
The controller:
//the collection to which the multiselect is bound:
$scope.contacts = dataService.lookups.contacts;
whenever an item is selected or unselected in the multiselect, this method is called:
$scope.updateBreezeContacts = function () {
//wipe out all the RequestContact entities
$scope.request.requestContacts.forEach(function (req) {
req.entityAspect.setDeleted();
});
//populate the RequestContact based on selected contacts
for (var i = 0; i < $scope.request.contacts.length; i++) {
var requestContact = dataService.createRequestContact($scope.request, $scope.request.contacts[i]);
$scope.request.requestContacts.push(requestContact);
}
where the createRequestContact method of the dataService actually does that:
manager.createEntity('RequestContact', { request: myRequest, contact: myContact});
Use case scenario:
- The request has one selected contact.
- User unselect the contact and then select another one from the list.
- Then she decides to reselect the one that was previously unselected. We now have two selected contacts.
- User hits the save button and the call to saveChanges is made. Breeze sends 3 entities to the server: the first contact with 'Deleted' status, the same contact again with 'Added' status, and finally the other contact that was selected, also with 'Added' status.
Is this what should be done when working with many-to-many associations ?
I actually get a server error ("not-null property references a null or transient value Business.Entities.RequestContact.Request") but before I draw any conclusions, I'd like to know if what I do on the client-side is correct.