locked
N:1 relationship : weird behavior RRS feed

  • Question

  • Hi all !

    I have many N:1 relations between contact and account. One is the "primarycustomer", that tells me to wich account my contact belongs, other are business related relationships that link contact to account, providing me some lookup fields for my contact.

    Everything works well when i create a contact via the contact list, with no preselected primarycustomer.

    The problem begins when i create a contact through the account's contact list (using the left nav pane, then "create a new contact" above the related view).

    In this case, the primarycustomerid is predefined, wich is great, but, any other lookup linking to an "account" entity are set to the primarycustomerid value...I have tried to null them in the js, forcing an update by "FireOnChange" but the values remain...

    How can i avoid this behavior for other fields than the true primarycustomerid ? What is this behavior due to ? I had a look to the mappings, but found no clue...

    Thanks in advance !

    EuG

     

    Friday, May 28, 2010 2:42 PM

Answers

  • EuG,

    The multiple, custom relationships between the Contact (1) to Account(N) are obviously the source of the problem, but also necessary for your purposes of tracking different kinds of relationships.  One circumvention to the whole situation may be an appropriate use of the built-in "Customer" Relationships model.  Both the Contact and the Account have a customizable "Customer Relationship" record that can tie any Contact(s) and any Account(s) together using customizable "Roles" to define the relationship between them.  I would sooner look into working with this, than creating a unique entity relationship for each possible tie between them.

    As for your code, well, I don't see anything wrong with it, except that I don't think you should have to be calling the "FireOnChange()" methods for the lookup fields.  It's very odd that the field you're watching does not change after being assigned "null".  Are you absolutely sure you're watching these fields in your debugger?

    crmForm.all.new_vendeurinitialid
    crmForm.all.new_vendeurcourantid
    crmForm.all.new_agencereferenceid
    crmForm.all.new_prestatairefacturationid

    Dave Berry
    • Marked as answer by EugeneMoulin Monday, May 31, 2010 2:36 PM
    Friday, May 28, 2010 4:30 PM
    Moderator

All replies

  • If you look at account_contacts relationship, and then click "Mappings", you will find a big list of mapping there, which is what you want to redefine.


    Daniel Cai | http://danielcai.blogspot.com
    Friday, May 28, 2010 2:58 PM
  • Daniel,

    The Mappings won't help, because as soon as you add one for any binding between two entities, the mappings for the remaining attributes that describe additional relationships between the entities will all automatically inherit the first mapping.  So the behavior Eugene points out is both highly reproducible and annoying.

    Eugene,

    Fire your code in the OnLoad action of the form, but only if the record/form state is in Create mode.  The SDK will help you figure out how to do this.  It's the only way around the problem.


    Dave Berry
    Friday, May 28, 2010 3:07 PM
    Moderator
  • Thanks Daniel, i see them and they seem to be the key to my problem.

    The new problem is that they seem to be "system"... So i cannot delete the mappings...

    The relationship is in parental mode. I could try to configure the cascade, but i could loose the primarycustomer predefinition behavior, right ?

    I'll read a bit more about relationships behavior and cascade configuration, i must have missed something.

     

    Thanks anyway !

     

    Friday, May 28, 2010 3:08 PM
  • David, 

    I had a quick try with the mappings, and removed one of them, and then the field is not mapped from Account to Contact. It's the way how th CRM mapping was designed, I see no reason why it's not working. Mappings are defined per relationship, I don't seem to see that the mappings of two relationships will interfere each other. 

    Eugene, 

    That's odd. I was able to delete a couple of the mappings for account_contacts relationship. And the mappings should not affect the cascading behaviors, they are two different things. 


    Daniel Cai | http://danielcai.blogspot.com
    Friday, May 28, 2010 3:23 PM
  • I don't know why, either, but that's how it works with custom relationships.  As soon as you establish the second relationship between two entities the value for both is mapped to a single one of the relationships--I can't remember the preference at this moment, as it's been a while since I had to tackle that problem.  I found that it was impossible to remove one mapping of the lookup fields for the related entity without removing all mappings for related lookups between both entities.

    Dave Berry
    Friday, May 28, 2010 3:36 PM
    Moderator
  • I should clarify that the problem affects only those mappings for lookup fields which pertain to the related entity.

    Dave Berry
    Friday, May 28, 2010 3:43 PM
    Moderator
  • Hmm, it could be my lack of observation. 

    I would be interested in knowing how it works out for Eugene. 

    Cheers,


    Daniel Cai | http://danielcai.blogspot.com
    Friday, May 28, 2010 3:52 PM
  • Hi David !

    Thanks for your answer.

    I did that already, in fact, it was my first try.

    Here is my code :

    switch (crmForm.FormType)
      {
        case CRMFORMTYPE_CREATE:
          // other code
          crmForm.all.new_civilite.DataValue = 1;
          crmForm.all.new_nbappels.DataValue = 0;
          crmForm.all.new_nbinterventions.DataValue = 0;
    
          //Try to null the account lookup fields : no effect
          crmForm.all.new_vendeurinitialid.DataValue = null;
          crmForm.all.new_vendeurinitialid.FireOnChange();
          crmForm.all.new_vendeurcourantid.DataValue = null;
          crmForm.all.new_vendeurcourantid.FireOnChange();
          crmForm.all.new_agencereferenceid.DataValue = null;
          crmForm.all.new_agencereferenceid.FireOnChange();
          crmForm.all.new_prestatairefacturationid.Datavalue = null;
          crmForm.all.new_prestatairefacturationid.FireOnChange();
    
          //...other code... but not concerning any of those lookup fields...      
    		
          break;
    
       //Other cases go there...

    Sorry for the french in the code.

    Those fields stand for partenerships between some of our customers and some dealers (represented by accounts entities).

    The code passes well in the good case, no error when executing the DataValue setting lines, no error on the FireOnChange() calls...

    To be more specific, only the last value remains, because other are changed (but not set to null) by further code.

    Very annoying to my mind...

    Another annoying thing : when i use the "immediate" window while debugging in visual studio, I first evaluate the DataValue before setting anything to null, it gives me the primarycustomerid's value. Then, i step forward, passing on the DataValue = null; line. Immediate evaluation still gives me primarycontactid's value. Then i step forward again, calling the FireOnChange method. And the value is still the same.

    It seems that that code has really no effect.

    I'll try to move it into an "new_prestatairefacturationid_change" event and see what happens.

    I keep you in touch !

    EuG

     

     

     

    Friday, May 28, 2010 3:55 PM
  • Thanks for your following Daniel !

    But the mappings you deleted were not displayed as system ones ? Or were they ?

    Thanks in advance !

    EuG

    Friday, May 28, 2010 3:58 PM
  • Hi EuG, 

    I believe only the accountid to parentcustomerid one is required in the mapping of account_contacts relationship. It seems that I can delete all the rest. 

    I am running on rollup 10, if that matters. 


    Daniel Cai | http://danielcai.blogspot.com
    Friday, May 28, 2010 4:07 PM
  • EuG,

    The multiple, custom relationships between the Contact (1) to Account(N) are obviously the source of the problem, but also necessary for your purposes of tracking different kinds of relationships.  One circumvention to the whole situation may be an appropriate use of the built-in "Customer" Relationships model.  Both the Contact and the Account have a customizable "Customer Relationship" record that can tie any Contact(s) and any Account(s) together using customizable "Roles" to define the relationship between them.  I would sooner look into working with this, than creating a unique entity relationship for each possible tie between them.

    As for your code, well, I don't see anything wrong with it, except that I don't think you should have to be calling the "FireOnChange()" methods for the lookup fields.  It's very odd that the field you're watching does not change after being assigned "null".  Are you absolutely sure you're watching these fields in your debugger?

    crmForm.all.new_vendeurinitialid
    crmForm.all.new_vendeurcourantid
    crmForm.all.new_agencereferenceid
    crmForm.all.new_prestatairefacturationid

    Dave Berry
    • Marked as answer by EugeneMoulin Monday, May 31, 2010 2:36 PM
    Friday, May 28, 2010 4:30 PM
    Moderator
  • David, Daniel,

    I have the same behavior David described :

    All my other contact-account N:1 relationships (or 1:N account-contact relationships) are "represented" as mappings into the account_contacts relation.

    I have been able to remove any other mappings (no problem getting rid of them, i don't rely on them for any purpose), but none of the mappings related to any of my contact-account N/1 relations...

    I'll try to update to rollup 10 on monday to see how it works...

    I've made another unsuccessful try : changing the relationship cascading behavior to "no cascading" but it had no effect...

    See you on monday guys, have a nice week end and thanks a lot for your help finding a way through, I really appreciate !

    EuG

     

    Friday, May 28, 2010 4:40 PM
  • Yes Dave, absolutely sure.

    I watch them before and after the DataValue = null; line... And the value never changes. I don't use a spy to watch them, but the "immediate" window. I don't think that it can have some influence on the evaluation...

    I'll dig on the customer relationship model first on monday morning. It sounds like a "role" could be what i reallly need, finally...

    My business purpose is to set an account as the contact's default retailer (crmForm.all.new_vendeurinitialid
    ), another acount as the default "agency" (crmForm.all.new_agencereferenceid), another one as the contact's "confidence partner" (crmForm.all.new_prestatairefacturationid) and a last one as the last "used" retailer (crmForm.all.new_vendeurcourantid).

    I have to go, it's 7PM here, my wife will kill me...once more :)

    Heve a nice week end !

    Many thanks and see you on monday.

    EuG

     

    Friday, May 28, 2010 5:00 PM
  • Hi Eugene,

    I had the same issue only a few weeks ago with unwanted mappings populating lookups. The script I used that seemed to work fine (add to onload) was:

    if(crmForm.FormType ==1)

    {

    crmForm.all.<attribute name goes here>.DataValue = null;

    }

     


    CRM4 MBSS
    Friday, May 28, 2010 11:12 PM
  • Hi Rob,

    Thanks a lot for your help, but i've already tried that code, and it doesn't work for all the fields that are populated.

    I feel like the solution is in the customer relation that Dave is talking about...

    EuG

     

    Monday, May 31, 2010 8:22 AM
  • Hi David,

    I had a look to the customer relationship entity.

    It is exactly what it is supposed to be : a way to define relations between contacts and account (or contacts and contacts, accounts and accounts...).

    That seems great, but, in my business, related accounts need to be present as lookup fields into the contact form. Lots of client side events have to respond to any change done to relation (for example, if we change the "default vendor", we have to display, in a read-only lookup, the "responsible vendor" of the default vendor, the "responsible agency" of this "default vendor" in one another read only lookup...

    And those data are to change very often.

    So, I don't think i'll be using this, mostly because of its display mode : My users want to have those info on the form and not in a related list. Fields are layed out in a "business understandable order" into the form, and i'm sure i won't convince the users that it is better to use it another way. And there would be lots of lost clientside interactivity, in my opinion.

    It could be possible to display those data into custom lookups, setting the data into the lookups in regard of the result of a query on the relation and a particular role, but there will be lots of code and queries to set it up...

    I'll keep on fighting with the lookups and if i find a way through, i'd let you know...

    Anyway, I mark your suggestion as the answer, because it is probably the "best pratcice" here...

    Thanks for your help !

    EuG

     

    Monday, May 31, 2010 2:35 PM
  • Daniel, David and Rob,

    I finally found a way through !

    May be this could help to understand the deep cause of this strange behavior..

    I've written down a line of code setting the DataValue to null in one of my event handlkers function (the parentcustomerid_change) and i fire the event in the onload event handler..

    And then my field is blanked ! It seems that setting the value to null in the Load handler is not the right place.

    My other lookups were set to null in other event handlers, that's why i've tried it for the new_prestatairefacturationid... And it works.

    May be, like asp.net, a kind of "ghost" event if fired betwwen the Page_Load and further code...

    Anyway, thanks again for helping me along the way !

    EuG

    Monday, May 31, 2010 2:53 PM
  • I'm glad you figured out the code problem.  Thanks for assigning me the answer anyway.  While my recommendation is indeed a better practice, since many of the Out-of-box reports for Accounts and Contacts use that relationship model as a pivot point for data, there's nothing wrong with the way you've done it.  (As for the issue with aesthetics, well, there are ways around it, but as you said they require time.  There are handy JS libraries out there to perform SOAP-based data queries against CRM which could help, but I think an embedded report would probably be easier to deploy.  But there's a cliche number of ways to skin that cat.)

    Thanks for including us on the resolution.


    Dave Berry
    Tuesday, June 1, 2010 5:26 PM
    Moderator