locked
Modifiy Relationship Property in IDataItem on custom Form RRS feed

  • Question

  • Hi all,

    I have a Relationship which itself has a Property "OrderNumber".  

            <RelationshipType ID="Applicationmanagement.ApplicationsetHasApplication" Base="System!System.Reference" Abstract="false" Accessibility="Public">
              <Property ID="OrderNumber" Key="false" Type="string" />
              <Source ID="Applicationmanagement.ApplicationsetHasApplication_Source" Type="ApplicationManagement.Applicationset" MinCardinality="0" MaxCardinality="2147483647"/>
              <Target ID="Applicationmanagement.ApplicationsetHasApplication_Target" Type="ApplicationManagement.Application" MinCardinality="0" MaxCardinality="2147483647"/>   
            </RelationshipType>

    I was able to load all relationships on my custom form and display them in a listview through a custom class. I am storing the original IDataItem as a property (Relationship) in my custom class for later access.

            private class ApplicationItemDataForView
            {
                private int _Order;
                private IDataItem _Target;
                private IDataItem _Releationship;
    
                public int Order
                {
                    get
                    {
                        int intVal;
                        try
                        {
    
                            intVal = this._Order;
                        }
                        finally
                        {
    
                        }
                        return intVal;
                    }
                    set
                    {
                        try
                        {
    
                            this._Order = value;
                        }
                        finally
                        {
    
                        }
                    }
                }
    
                public IDataItem Target
                {
                    get
                    {
                        IDataItem item;
                        try
                        {
                            item = this._Target;
                        }
                        finally
                        {
    
                        }
                        return item;
                    }
                    set
                    {
                        try
                        {
    
                            this._Target = value;
                        }
                        finally
                        {
    
                        }
                    }
                }
    
                public IDataItem Relationship
                {
                    get
                    {
                        IDataItem item;
                        try
                        {
                            item = this._Releationship;
                        }
                        finally
                        {
    
                        }
                        return item;
                    }
                    set
                    {
                        try
                        {
    
                            this._Releationship = value;
                        }
                        finally
                        {
    
                        }
                    }
                }
            }

    Now I want to modify the OrderNumber Property through the custom form (button click) and store it back to the database. I tried this but its not working.

            private void UpdateApplicationOrder()
            {
                foreach (ApplicationItemDataForView item in lvReleatedApplications.ItemsSource)
                {
                    item.Relationship["OrderNumber"] = 1;
                    Microsoft.EnterpriseManagement.UI.Extensions.Shared.ConsoleContextHelper.Instance.UpdateInstance(item.Relationship);
                    
                }
            }

    The code is running without an exception but the OrderNumber is not commited to the database. How do I update such a property using my IDataItem object?

    Thanks

    Sunday, September 8, 2013 12:34 PM

Answers

  • I am not sure how/if this is possible directly from a regular IDataItem.

    Looking at how you obtained relationshipInstances, you cannot do:

    relationshipInstances[index]["OrderNumber"] = 1;

    and/or

    IDataItem targetinst = (IDataItem)relationshipInstances[index]["Target"]);

    ?

    This is how it works on the Software Form, and I see you have used the same method using DataAccessQuery to obtain your items.

    I would suggest examining Microsoft.EnterpriseManagement.ServiceManager.ConfigurationManagement.Forms...


    Rob Ford scsmnz.net
    Cireson www.cireson.com
    For a free SCSM 2012 Notify Analyst app click here


    • Edited by Rob.Ford Monday, September 9, 2013 10:41 PM
    • Proposed as answer by Rob.Ford Tuesday, September 17, 2013 3:53 AM
    • Marked as answer by Andreas BaumgartenMVP Saturday, October 26, 2013 10:18 PM
    Monday, September 9, 2013 10:39 PM
  • Or, depending on your requirement, you might be able to use a nested relationship (like RA -> reviewers -> reviewer is user) such as:

    Application Set -> New Class With Order Number -> Application


    Rob Ford scsmnz.net
    Cireson www.cireson.com
    For a free SCSM 2012 Notify Analyst app click here

    • Proposed as answer by Rob.Ford Tuesday, September 17, 2013 3:53 AM
    • Marked as answer by Andreas BaumgartenMVP Saturday, October 26, 2013 10:18 PM
    Monday, September 9, 2013 10:48 PM

All replies

  • If you use a type projection that contains your relationship, your custom form Data Context will contain the relationship data and you won't have to store this in your class...

    Then you could do:

    (formInstance["Alias_from_typeprojection"] as IDataItem)["OrderNumber"] = 1;

    And, when you commit, you commit your formInstance, not the relationship target instance.


    Rob Ford scsmnz.net
    Cireson www.cireson.com
    For a free SCSM 2012 Notify Analyst app click here

    Monday, September 9, 2013 6:27 AM
  • Hey Rob,

    thanks for your reply. Not sure If I unterstand it right,

    you mean something like this ?

                IDataItem i = this.DataContext as IDataItem;
                
                foreach (IDataItem application in (DataItemCollection)(i["ApplicationsetHasApplication"]))
                {
                    string str = "Hello";
                }  

    This works, but "application" is then the related appliation self and its not the relationship instance which has the property I want to set! Do I miss something?

    I mean the object is the Target (of Class Application) but I want to have the relatiohsiph instance self.

    I allready loaded these instances through this code, but I dont know how to modify them as its not coming from the datacontext, I mean its loaded beside....

    private void FetchApplicationItems(Guid sourceInstanceId, Guid relationshipId)
            {
                AsyncCallback callback2 = null;
                try
                {
                    Dictionary<string, object> dictionary = new Dictionary<string, object>();
                    dictionary.Add("SourceID", sourceInstanceId.ToString());
                    dictionary.Add("RelationShipTypeId", relationshipId);
                    if (callback2 == null)
                    {
                        callback2 = delegate(IAsyncResult result)
                        {
                            try
                            {
                                try
                                {
                                    lock (this.LockApplicationItemView)
                                    {
                                        IList<IDataItem> relationshipInstances = DataAccessQuery.EndDataAccessQuery(result);
        
    
                                        if ((relationshipInstances != null) && (relationshipInstances.Count > 0))
                                        {
                                            this.ApplicationItems = this.UpdateApplicationItemListView(relationshipInstances);
                                        }
                                    }
                                }
                                catch (Exception exception)
                                {
                                    //ErrorDialog dialog = new ErrorDialog();
                                    //dialog.set_ErrorTitle(ConfigurationManagement.ErorInFetchingdata);
                                    //dialog.set_Severity(ConsoleJobExceptionSeverity.Error);
                                    //dialog.ShowDialog();
    
                                    throw;
                                }
                                finally
                                {
                                    //this.SoftwareFilledEvent.Set();
                                }
                            }
                            catch (Exception e)
                            {
                                throw e;
                            }
    
                        };
                    }
                    AsyncCallback callback = callback2;
                    new DataAccessQuery().QueryAdapterASync(dictionary, null, EnterpriseManagementRelationshipObjectAdapter.AdapterName, typeof(EnterpriseManagementRelationshipObjectAdapter), ManagementGroupDataSource.DataSourceName, callback);
                }
                catch
                {
                    throw new Exception();
                }
    
            }




    Monday, September 9, 2013 8:18 AM
  • Ok, I think I am getting closer. Now I have this piece of code

                ManagementPackRelationship relClass = mg.EntityTypes.GetRelationshipClass(new Guid("d93f2b71-fff4-3051-7fbd-ab5ba7a5de20"));
    
                foreach (ApplicationItemDataForView applicationItem in lvReleatedApplications.ItemsSource as IList<ApplicationItemDataForView>)
                {
    
                    string id = applicationItem.Relationship["$Id$"].ToString();
                    EnterpriseManagementRelationshipObject<EnterpriseManagementObject> rel = mg.EntityObjects.GetRelationshipObject<EnterpriseManagementObject>(new Guid(id), ObjectQueryOptions.Default);
                    
                    rel[relClass, "OrderNumber"].Value = "2";
                    rel.Commit();
                }

    This works find when I enter the GUID ID of the Realtionship gathered via smlets in powershell manually. But how do I get this GUID from the IDataItem Realtionship Instance ?

    this line is not working

    string id = applicationItem.Relationship["$Id$"].ToString();
    

    Seems like there is no property $Id$ as it is on the target. Can I get the GUID from the default datacontext ?


    Monday, September 9, 2013 11:08 AM
  • Why did you define the property on the relationship itself? Why not on the application class? Then you wouldn't have any of these issues. Only a very few relationships from the product use this technique, for software items and health service communication.


    Rob Ford scsmnz.net
    Cireson www.cireson.com
    For a free SCSM 2012 Notify Analyst app click here


    • Edited by Rob.Ford Monday, September 9, 2013 7:58 PM
    Monday, September 9, 2013 7:47 PM
  • Hey Rob, because I need to have multiple relationship imstances for the same application with different property valus for different targets (class applicationset). If i define it on the application class, i cant have different values for the same application. I know that the product is using this technique for software items and I am using it for the same pupose. (Applications are discovered from SCCM) We need this solution urgently....Could you please help me with this? The only piece missing is the Guid of the realtionship instance from IDataItem. Possible or not? Thank you so much!
    Monday, September 9, 2013 8:58 PM
  • I am not sure how/if this is possible directly from a regular IDataItem.

    Looking at how you obtained relationshipInstances, you cannot do:

    relationshipInstances[index]["OrderNumber"] = 1;

    and/or

    IDataItem targetinst = (IDataItem)relationshipInstances[index]["Target"]);

    ?

    This is how it works on the Software Form, and I see you have used the same method using DataAccessQuery to obtain your items.

    I would suggest examining Microsoft.EnterpriseManagement.ServiceManager.ConfigurationManagement.Forms...


    Rob Ford scsmnz.net
    Cireson www.cireson.com
    For a free SCSM 2012 Notify Analyst app click here


    • Edited by Rob.Ford Monday, September 9, 2013 10:41 PM
    • Proposed as answer by Rob.Ford Tuesday, September 17, 2013 3:53 AM
    • Marked as answer by Andreas BaumgartenMVP Saturday, October 26, 2013 10:18 PM
    Monday, September 9, 2013 10:39 PM
  • Or, depending on your requirement, you might be able to use a nested relationship (like RA -> reviewers -> reviewer is user) such as:

    Application Set -> New Class With Order Number -> Application


    Rob Ford scsmnz.net
    Cireson www.cireson.com
    For a free SCSM 2012 Notify Analyst app click here

    • Proposed as answer by Rob.Ford Tuesday, September 17, 2013 3:53 AM
    • Marked as answer by Andreas BaumgartenMVP Saturday, October 26, 2013 10:18 PM
    Monday, September 9, 2013 10:48 PM