Bug Report B232305
Visible to All Users

Core - Linked objects are not removed from the link view immediately

created 12 years ago

Start MainDemo.Win.
Open the Department DetaiView.
Unlink all contacts.
Click Link - the displayed ListView does not contain unlinked contacts.
Click Save and Refresh, link a Contact to the Department.
Click Link - the linked Contact is still there.

Answers approved by DevExpress Support

created 12 years ago (modified 9 years ago)

We have fixed the issue described in this ticket and will include the fix in our next maintenance update. To apply this solution before the official update, request a hotfix by clicking the corresponding link for product versions you require.

Note: Hotfixes may be unavailable for beta versions and updates that are about to be released.

Additional information:

Hello,
We decided to change the default value for the LinkUnlinkController.ExcludeLinkedObjects property from true to false, which will fix this issue.
Our experience shows that implementing a universal solution for this task is not as easy as it appeared at the outset, because of a large number of possible scenarios.
For instance, our first implementation (SystemModules.Link - Exclude objects that are already linked to an object from the Link ListView) used the InOperator and it handled unsaved objects (InTransaction) very well. However, we observed that this InOperator-based implementation had two drawbacks:

  1. Linking a large number of objects at once (we first observed this while performing tests with our internal apps) may lead to reaching the parameter limit in a query for certain database servers (e.g., MS SQL Server, Oracle, etc.): http://stackoverflow.com/questions/845931/
    This is further explained at Automatically split queries with In-Operator when too many operands are involved.
  2. When a nested ListView is in server mode, this solution required loading all objects from the detail collection to work properly. We had no reports about this problem from our customers (quite likely because nested ListViews do not typically contain lots of records, so they rarely require server mode), but it might be a problem for them in the future.
    So, we changed our initial implementation so as not to use the InOperator and to eliminate the aforementioned behaviors. However, it introduced the behavior described in this ticket.
    While it seems that no generic solution combining only the advantages of the solutions I described exists for this particular scenario, it is still possible to filter out linked objects in your end application depending on the precise business scenario and requirements. It is possible because the LinkUnlinkController responsible for the linking operations provides plenty of events (SystemModules.Link - Provide events to create and customize a custom Link ListView) and virtual methods (e.g., CreateLinkView) to customize the default behavior.
    For instance, you may find the following code helpful if you must filter out excluded objects if you are sure that you will not hit the database server limit on the number of parameters in a query:
C#
using System.Collections; using DevExpress.Data.Filtering; using DevExpress.ExpressApp.SystemModule; public class MyLinkUnlinkController : LinkUnlinkController /*use WebLinkUnlinkController in ASP.NET*/ { protected override void OnActivated() { base.OnActivated(); ExcludeLinkedObjects = true; } protected override View CreateLinkView() { ListView result = (ListView)base.CreateLinkView(); if (ExcludeLinkedObjects && View.CollectionSource.DataAccessMode == CollectionSourceDataAccessMode.Client && View.CollectionSource.List.Count > 0) { ArrayList idList = new ArrayList(View.CollectionSource.List.Count); foreach (object item in View.CollectionSource.List) { idList.Add(ObjectSpace.GetKeyValue(item)); } CriteriaOperator associatedCollectionCriteria = new InOperator(ObjectSpace.GetKeyPropertyName(View.ObjectTypeInfo.Type), idList); result.CollectionSource.Criteria[CriteriaKeyForLinkView] = new NotOperator(associatedCollectionCriteria); } return result; } }
    Comments (2)

      Does the suggested code still works in the current version (21.1.5)? I tried to implement it and had the following problem:
      Lets say there is one object linked. I unlink it and then I link it again without committing in between. When the CreateLinkView method is called 'View.CollectionSource.List.Count' is always 0 and thus the object that was unlinked in the transaction is not displayed in the link view.

      DevExpress Support Team 3 years ago

        @Bernd, I tested this code in our demo with the latest version (v21.1.6) and it seems to work correctly. I cannot reproduce the issue you described. Please submit a new ticket and attach a small sample project that demonstrates the issue.

        Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

        Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.