Creating TypeProjections for System Center Service Manager 2012

A common issue I see with Service Manager deployments are Queues, Views, etc created with unnecessary TypeProjections.  This can cause huge delays in processing workflows and causing issues with Console performance.  The biggest culprit I see is within Service Requests. Below I will discuss this briefly, also attached is a copy of an example Management Pack with a generic TypeProjection for Service Requests with just the Affected User and Assigned to User relationship.s

Let's take a quick look at the out of box TypeProjections for Service Requests.  As you can see below there are 4 out of box Type Projections. You have in order from top to bottom

  1. Service Request (advanced)
  2. Service Request (typical)
  3. Serivce Request and Activity
  4. System.WorkItem.ServiceRequest.View.SLAProjectionType (This one doesn't have a display string)

 So let's say you want to create a queue or a view that refers to the Affected User, the only choice you have is Service Request (Advanced) which has 15 relationships and even some nested ones. 

      <TypeProjections>

        <TypeProjection ID="System.WorkItem.ServiceRequestProjection" Accessibility="Public" Type="CoreService!System.WorkItem.ServiceRequest">

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="AssignedTo" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemClosedByUser']$" Alias="ClosedBy" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemCreatedByUser']$" Alias="CreatedBy" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="AffectedUser" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemRelatesToConfigItem']$" Alias="RelatedConfigItems" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem']$" Alias="AboutConfigItem" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem' TypeConstraint='System!System.Service']$" Alias="AffectedServices" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem']$" Alias="RelatedWorkItems">

            <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="RelatedWorkItemAssignedTo" />

          </Component>

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem' SeedRole='Target']$" Alias="RelatedWorkItemSource">

            <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="RelatedWorkItemAssignedTo" />

          </Component>

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemHasFileAttachment']$" Alias="FileAttachments">

            <Component Path="$Target/Path[Relationship='SupportingItem!System.FileAttachmentAddedByUser']$" Alias="FileAttachmentAddedBy" />

          </Component>

          <Component Path="$Target/Path[Relationship='CoreKnowledge!System.EntityLinksToKnowledgeDocument']$" Alias="RelatedKnowledgeArticles" />

          <Component Path="$Target/Path[Relationship='Catalog!System.WorkItemRelatesToRequestOffering']$" Alias="RelatedRequestOffering" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemHasActionLog' TypeConstraint='WorkItem!System.WorkItem.TroubleTicket.ActionLog']$" Alias="ActionLog" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemHasCommentLog' TypeConstraint='WorkItem!System.WorkItem.TroubleTicket.AnalystCommentLog']$" Alias="AnalystCommentLog" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemHasCommentLog' TypeConstraint='WorkItem!System.WorkItem.TroubleTicket.UserCommentLog']$" Alias="EndUserCommentLog" />

        </TypeProjection>

        <TypeProjection ID="System.WorkItem.ServiceRequestViewProjection" Accessibility="Public" Type="CoreService!System.WorkItem.ServiceRequest">

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="AssignedTo" />

        </TypeProjection>

        <TypeProjection ID="System.WorkItem.ServiceRequestAndActivityViewProjection" Accessibility="Public" Type="CoreService!System.WorkItem.ServiceRequest">

          <Component Path="$Target/Path[Relationship='CoreActivity!System.WorkItemContainsActivity']$" Alias="Activity" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="AssignedTo" />

        </TypeProjection>

        <TypeProjection ID="System.WorkItem.ServiceRequest.View.SLAProjectionType" Accessibility="Public" Type="CoreService!System.WorkItem.ServiceRequest">

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="AssignedTo" />

          <Component Path="$Target/Path[Relationship='SLACore!System.WorkItemHasSLAInstanceInformation' SeedRole='Source' TypeConstraint='SLACore!System.SLA.Instance.TimeInformation']$" Alias="SLAInstances">

            <Component Path="$Context/Path[Relationship='SLACore!System.SLA.Instance.InformationRefersToSLAConfiguration']$" Alias="SLAConfiguration" />

          </Component>

        </TypeProjection>

      </TypeProjections>

By using the Service Request (Advanced) TypeProjection above you could put your environment is a poor shape that it doesn't need to be in.  To remedy this we will create some new TypeProjections that can be used as (Combination Classes) in the console.

  1. Below is an example of a TypeProjection with just Assigned to User and Affected User, this will drastically reduce the time it takes to query the object due to all the other relationships not being in the query.  Note this does not affect the Tickets/etc later as you can query an EnterpriseManagement object based on any TypeProjection that is related to it, this is for another topic though.  From here you can add more components or remove them.  

  <TypeDefinitions>

    <EntityTypes>

      <TypeProjections>

        <TypeProjection ID="CustomServiceRequestBasicProjection" Accessibility="Public" Type="CoreService!System.WorkItem.ServiceRequest">

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="AssignedTo" />

          <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="AffectedUser" />

        </TypeProjection>

      </TypeProjections>

    </EntityTypes>

  </TypeDefinitions>

Custom.ServiceRequest.Projections.xml