locked
Type Projection RRS feed

  • Question

  • Hi All

    I have been trying to create a type projection, from which I could create a view to show all Incidents with Activities. I have been using the Management Pack on this site as an example, which does exactly what I need, but with Change Requests http://blogs.technet.com/b/servicemanager/archive/2010/03/04/create-a-view-of-all-activities-that-are-a-part-of-a-change-request-and-see-the-change-request-information-in-the-view-columns.aspx

    I have been trying to use the syntax in this as a reference to create the type projection, and then go in and create the view through the console. Here is the management pack I have created in it's latest form. It imports fine, and I can create a view from it but it doesn't work the same as the change request view above.

    <ManagementPack ContentReadable="true" SchemaVersion="1.1" OriginalSchemaVersion="1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <Manifest>
    
      <Identity>
    
       <ID>IncidentActivity.Views</ID>
    
       <Version>7.0.5244.1</Version>
    
      </Identity>
    
      <Name>Activity Management Views</Name>
    
      <References>
    
       <Reference Alias="System">
    
        <ID>System.Library</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
       <Reference Alias="WorkItem">
    
        <ID>System.WorkItem.Library</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
       <Reference Alias="CoreChange">
    
        <ID>System.WorkItem.ChangeRequest.Library</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
       <Reference Alias="CoreIncident">
    
        <ID>System.WorkItem.Incident.Library</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
       <Reference Alias="Activity">
    
        <ID>ServiceManager.ActivityManagement.Library</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
       <Reference Alias="CoreActivity">
    
        <ID>System.WorkItem.Activity.Library</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
       <Reference Alias="SMConsole">
    
        <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Console</ID>
    
        <Version>7.0.5244.0</Version>
    
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
    
       </Reference>
    
      </References>
    
     </Manifest>
    
     <TypeDefinitions>
    
      <EntityTypes>
    
       <TypeProjections>
    
        <TypeProjection ID="System.WorkItem.ActivityChangeRequestViewProjection" Accessibility="Public" Type="CoreActivity!System.WorkItem.Activity">
    
         <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="ActivityAssignedTo" />
    
         <Component Path="$Target/Path[Relationship='CoreActivity!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CoreChange!System.WorkItem.ChangeRequest']$" Alias="ParentWorkItem" />
    
        </TypeProjection>
    
        <TypeProjection ID="System.WorkItem.ActivityIncidentViewProjection" Accessibility="Public" Type="CoreActivity!System.WorkItem.Activity">
    
         <Component Path="$Target/Path[Relationship='CoreActivity!System.WorkItemContainsActivity']$" Alias="ParentWorkItem1" />
    
        </TypeProjection>
    
       </TypeProjections>
    
      </EntityTypes>
    
     </TypeDefinitions>
    
     <Categories>
    
      <Category ID="ActivityManagement.Categories.AllActivitiesinChangeRequest" Target="ActivityManagement.Views.AllActivitiesinChangeRequest" Value="SMConsole!Microsoft.EnterpriseManagement.ServiceManager.UI.Console.ViewTasks" />
    
     </Categories>
    
    
    </ManagementPack>
    

    Thanks 

    Tuesday, March 1, 2011 3:27 PM

Answers

  • First thing you'll need to do is add a seedrole and type constraint to your new type projection's component element.

    <Component Path="$Target/Path[Relationship='CoreActivity!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CoreIncident!System.WorkItem.Incident']$" Alias="ParentWorkItem1" />
    
    
    

    This will ensure your type projection is doing what you want it to do (activities are the seed and parent work items (specifically: incidents) are a component)

    If you have also copied the view from that blog post, make sure all the references to ParentWorkItem are changed to ParentWorkItem1 to match the component's alias name.
    And, again, if you have copied the view from the blog post, you should include the ActivityAssignedTo component in your new type projection as well (since that view makes use of it)

    You won't be able to use the console to create a view displaying the change request fields from this type projection. It will have to be created in the management pack.

    Let me know if that helps or not :) I just built it myself and it worked ok..eg: I have a view of all activities in all open incidents. (But I had to copy the views from that blog post..i couldn't create them in the console)

    • Marked as answer by Nick Dattilo Wednesday, March 2, 2011 4:05 PM
    Tuesday, March 1, 2011 5:42 PM
  • My pleasure :)

    Here's the view I created if you want to use it as a reference or compare it to the one from the blog (sorry, i just have just posted this earlier :) )

    <View ID="ActivityManagement.Views.AllActivitiesinIncident" Accessibility="Public" Enabled="true" Target="CoreActivity!System.WorkItem.Activity" TypeID="SMConsole!GridViewType" Visible="true">
        <Category>NotUsed</Category>
        <Data>
         <Adapters>
          <Adapter AdapterName="dataportal:EnterpriseManagementObjectProjectionAdapter">
           <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>
           <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.EnterpriseManagementObjectProjectionAdapter</AdapterType>
          </Adapter>
          <Adapter AdapterName="viewframework://Adapters/AdvancedList">
           <AdapterAssembly>Microsoft.EnterpriseManagement.UI.ViewFramework</AdapterAssembly>
           <AdapterType>Microsoft.EnterpriseManagement.UI.ViewFramework.AdvancedListSupportAdapter</AdapterType>
          </Adapter>
         </Adapters>
         <ItemsSource>
          <AdvancedListSupportClass DataTypeName="" AdapterName="viewframework://Adapters/AdvancedList" FullUpdateAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" DataSource="mom:ManagementGroup" IsRecurring="true" RecurrenceFrequency="{x:Static s:Int32.MaxValue}" FullUpdateFrequency="1" Streaming="true" xmlns="clr-namespace:Microsoft.EnterpriseManagement.UI.ViewFramework;assembly=Microsoft.EnterpriseManagement.UI.ViewFramework" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib">
           <AdvancedListSupportClass.Parameters>
            <QueryParameter Parameter="TypeProjectionId" Value="$MPElement[Name='System.WorkItem.ActivityIncidentViewProjection']$" />
           </AdvancedListSupportClass.Parameters>
          </AdvancedListSupportClass>
         </ItemsSource>
         <Criteria>
          <QueryCriteria Adapter="omsdk://Adapters/Criteria" xmlns="http://tempuri.org/Criteria.xsd">
           <Criteria>
            <FreeformCriteria>
             <Freeform>
              <Criteria xmlns="http://Microsoft.EnterpriseManagement.Core.Criteria/">
               <Expression>
                <SimpleExpression>
                 <ValueExpressionLeft>
                  <Property>$Context/Path[Relationship='CoreActivity!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CoreIncident!System.WorkItem.Incident']/Property[Type='CoreIncident!System.WorkItem.Incident']/Status$</Property>
                 </ValueExpressionLeft>
                 <Operator>NotEqual</Operator>
                 <ValueExpressionRight>
                  <Value>$MPElement[Name="CoreIncident!IncidentStatusEnum.Closed"]$</Value>
                 </ValueExpressionRight>
                </SimpleExpression>
               </Expression>
              </Criteria>
             </Freeform>
            </FreeformCriteria>
           </Criteria>
          </QueryCriteria>
         </Criteria>
        </Data>
        <Presentation>
         <Columns>
          <mux:ColumnCollection xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mux="http://schemas.microsoft.com/SystemCenter/Common/UI/Views/GridView" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:datebinding="clr-namespace:Microsoft.EnterpriseManagement.UI.SdkDataAccess.Common;assembly=Microsoft.EnterpriseManagement.UI.SdkDataAccess">
           <mux:Column Name="id" DisplayMemberBinding="{Binding Path=Id}" Width="100" DisplayName="Header_Id" Property="Id$ReturnValueAsBigInt$" DataType="s:Int32" />
           <mux:Column Name="title" DisplayMemberBinding="{Binding Path=Title}" Width="200" DisplayName="Header_Title" Property="Title" DataType="s:String" />
           <mux:Column Name="parentDisplayName" DisplayMemberBinding="{Binding Path=ParentWorkItem/DisplayName}" Width="200" DisplayName="Header_Parent_DisplayName" Property="ParentWorkItem/DisplayName" DataType="s:String" />
           <mux:Column Name="parentStatus" DisplayMemberBinding="{Binding Path=ParentWorkItem/Status.DisplayName}" Width="100" DisplayName="Header_Parent_Status" Property="ParentWorkItem/Status.DisplayName" DataType="s:String" />
           <mux:Column Name="aDisplayName" DisplayMemberBinding="{Binding Path=ActivityAssignedTo.DisplayName}" Width="100" DisplayName="Header_Assigned_To" Property="ActivityAssignedTo.DisplayName" DataType="s:String" />
           <mux:Column Name="statusDisplayName" DisplayMemberBinding="{Binding Path=Status.DisplayName}" Width="100" DisplayName="Header_Status" Property="Status.Ordinal" DataType="s:Double" />
           <mux:Column Name="stageDisplayName" DisplayMemberBinding="{Binding Path=Stage.DisplayName}" Width="100" DisplayName="Header_Stage" Property="Stage.Ordinal" DataType="s:Double" />
          </mux:ColumnCollection>
         </Columns>
         <ViewStrings>
          <ViewString ID="Header_Id">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Id"]$</ViewString>
          <ViewString ID="Header_Title">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Title"]$</ViewString>
          <ViewString ID="Header_Parent_DisplayName">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_DisplayName"]$</ViewString>
          <ViewString ID="Header_Parent_Status">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_Status"]$</ViewString>
          <ViewString ID="Header_Assigned_To">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Assigned_To"]$</ViewString>
          <ViewString ID="Header_Status">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Status"]$</ViewString>
          <ViewString ID="Header_Stage">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Stage"]$</ViewString>
         </ViewStrings>
        </Presentation>
       </View>
    

    It requires a couple StringResources, too..I only copied the ones from the blog post and gave them new names

    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Id" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Stage" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Status" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Title" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Assigned_To" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_DisplayName" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_Status" />
    
    

    And I just put it in the activity management folder

    <FolderItem ElementID="ActivityManagement.Views.AllActivitiesinIncident" ID="ActivityManagement.FolderItems.AllActivitiesinIncident" Folder="Activity!ServiceManager.Console.ActivityManagement" />
    
    • Marked as answer by Nick Dattilo Wednesday, March 2, 2011 4:05 PM
    Tuesday, March 1, 2011 9:34 PM

All replies

  • First thing you'll need to do is add a seedrole and type constraint to your new type projection's component element.

    <Component Path="$Target/Path[Relationship='CoreActivity!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CoreIncident!System.WorkItem.Incident']$" Alias="ParentWorkItem1" />
    
    
    

    This will ensure your type projection is doing what you want it to do (activities are the seed and parent work items (specifically: incidents) are a component)

    If you have also copied the view from that blog post, make sure all the references to ParentWorkItem are changed to ParentWorkItem1 to match the component's alias name.
    And, again, if you have copied the view from the blog post, you should include the ActivityAssignedTo component in your new type projection as well (since that view makes use of it)

    You won't be able to use the console to create a view displaying the change request fields from this type projection. It will have to be created in the management pack.

    Let me know if that helps or not :) I just built it myself and it worked ok..eg: I have a view of all activities in all open incidents. (But I had to copy the views from that blog post..i couldn't create them in the console)

    • Marked as answer by Nick Dattilo Wednesday, March 2, 2011 4:05 PM
    Tuesday, March 1, 2011 5:42 PM
  • Thanks Aaron

    I didn't realize we would need to create the view in the management pack, so I'll give it a shot and see if I can get it working.

    Thanks again for your help

    Tuesday, March 1, 2011 7:06 PM
  • My pleasure :)

    Here's the view I created if you want to use it as a reference or compare it to the one from the blog (sorry, i just have just posted this earlier :) )

    <View ID="ActivityManagement.Views.AllActivitiesinIncident" Accessibility="Public" Enabled="true" Target="CoreActivity!System.WorkItem.Activity" TypeID="SMConsole!GridViewType" Visible="true">
        <Category>NotUsed</Category>
        <Data>
         <Adapters>
          <Adapter AdapterName="dataportal:EnterpriseManagementObjectProjectionAdapter">
           <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>
           <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.EnterpriseManagementObjectProjectionAdapter</AdapterType>
          </Adapter>
          <Adapter AdapterName="viewframework://Adapters/AdvancedList">
           <AdapterAssembly>Microsoft.EnterpriseManagement.UI.ViewFramework</AdapterAssembly>
           <AdapterType>Microsoft.EnterpriseManagement.UI.ViewFramework.AdvancedListSupportAdapter</AdapterType>
          </Adapter>
         </Adapters>
         <ItemsSource>
          <AdvancedListSupportClass DataTypeName="" AdapterName="viewframework://Adapters/AdvancedList" FullUpdateAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" DataSource="mom:ManagementGroup" IsRecurring="true" RecurrenceFrequency="{x:Static s:Int32.MaxValue}" FullUpdateFrequency="1" Streaming="true" xmlns="clr-namespace:Microsoft.EnterpriseManagement.UI.ViewFramework;assembly=Microsoft.EnterpriseManagement.UI.ViewFramework" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib">
           <AdvancedListSupportClass.Parameters>
            <QueryParameter Parameter="TypeProjectionId" Value="$MPElement[Name='System.WorkItem.ActivityIncidentViewProjection']$" />
           </AdvancedListSupportClass.Parameters>
          </AdvancedListSupportClass>
         </ItemsSource>
         <Criteria>
          <QueryCriteria Adapter="omsdk://Adapters/Criteria" xmlns="http://tempuri.org/Criteria.xsd">
           <Criteria>
            <FreeformCriteria>
             <Freeform>
              <Criteria xmlns="http://Microsoft.EnterpriseManagement.Core.Criteria/">
               <Expression>
                <SimpleExpression>
                 <ValueExpressionLeft>
                  <Property>$Context/Path[Relationship='CoreActivity!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CoreIncident!System.WorkItem.Incident']/Property[Type='CoreIncident!System.WorkItem.Incident']/Status$</Property>
                 </ValueExpressionLeft>
                 <Operator>NotEqual</Operator>
                 <ValueExpressionRight>
                  <Value>$MPElement[Name="CoreIncident!IncidentStatusEnum.Closed"]$</Value>
                 </ValueExpressionRight>
                </SimpleExpression>
               </Expression>
              </Criteria>
             </Freeform>
            </FreeformCriteria>
           </Criteria>
          </QueryCriteria>
         </Criteria>
        </Data>
        <Presentation>
         <Columns>
          <mux:ColumnCollection xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mux="http://schemas.microsoft.com/SystemCenter/Common/UI/Views/GridView" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:datebinding="clr-namespace:Microsoft.EnterpriseManagement.UI.SdkDataAccess.Common;assembly=Microsoft.EnterpriseManagement.UI.SdkDataAccess">
           <mux:Column Name="id" DisplayMemberBinding="{Binding Path=Id}" Width="100" DisplayName="Header_Id" Property="Id$ReturnValueAsBigInt$" DataType="s:Int32" />
           <mux:Column Name="title" DisplayMemberBinding="{Binding Path=Title}" Width="200" DisplayName="Header_Title" Property="Title" DataType="s:String" />
           <mux:Column Name="parentDisplayName" DisplayMemberBinding="{Binding Path=ParentWorkItem/DisplayName}" Width="200" DisplayName="Header_Parent_DisplayName" Property="ParentWorkItem/DisplayName" DataType="s:String" />
           <mux:Column Name="parentStatus" DisplayMemberBinding="{Binding Path=ParentWorkItem/Status.DisplayName}" Width="100" DisplayName="Header_Parent_Status" Property="ParentWorkItem/Status.DisplayName" DataType="s:String" />
           <mux:Column Name="aDisplayName" DisplayMemberBinding="{Binding Path=ActivityAssignedTo.DisplayName}" Width="100" DisplayName="Header_Assigned_To" Property="ActivityAssignedTo.DisplayName" DataType="s:String" />
           <mux:Column Name="statusDisplayName" DisplayMemberBinding="{Binding Path=Status.DisplayName}" Width="100" DisplayName="Header_Status" Property="Status.Ordinal" DataType="s:Double" />
           <mux:Column Name="stageDisplayName" DisplayMemberBinding="{Binding Path=Stage.DisplayName}" Width="100" DisplayName="Header_Stage" Property="Stage.Ordinal" DataType="s:Double" />
          </mux:ColumnCollection>
         </Columns>
         <ViewStrings>
          <ViewString ID="Header_Id">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Id"]$</ViewString>
          <ViewString ID="Header_Title">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Title"]$</ViewString>
          <ViewString ID="Header_Parent_DisplayName">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_DisplayName"]$</ViewString>
          <ViewString ID="Header_Parent_Status">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_Status"]$</ViewString>
          <ViewString ID="Header_Assigned_To">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Assigned_To"]$</ViewString>
          <ViewString ID="Header_Status">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Status"]$</ViewString>
          <ViewString ID="Header_Stage">$MPElement[Name="ActivityManagement.Views.AllActivitiesinIncident.Header_Stage"]$</ViewString>
         </ViewStrings>
        </Presentation>
       </View>
    

    It requires a couple StringResources, too..I only copied the ones from the blog post and gave them new names

    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Id" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Stage" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Status" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Title" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Assigned_To" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_DisplayName" />
    <StringResource ID="ActivityManagement.Views.AllActivitiesinIncident.Header_Parent_Status" />
    
    

    And I just put it in the activity management folder

    <FolderItem ElementID="ActivityManagement.Views.AllActivitiesinIncident" ID="ActivityManagement.FolderItems.AllActivitiesinIncident" Folder="Activity!ServiceManager.Console.ActivityManagement" />
    
    • Marked as answer by Nick Dattilo Wednesday, March 2, 2011 4:05 PM
    Tuesday, March 1, 2011 9:34 PM
  • Hi Aaron

    I went through and updated the view with the correct references. Thanks for the post above with the view, it was helpful to be able to compare it against yours. I was then able to import the management pack and voila, the view was there and I could group by Incident. Thanks again for your help!

    Nick

    Wednesday, March 2, 2011 4:26 PM