Virtual Entities: Are they a fit for your production environment?

If you were excited about the release of Virtual Entities as part of Microsoft Dynamics 365, you were probably equally puzzled about the limited documentation available. There is virtually (pun intended) no information on integrating Virtual Entities (VE) into a production environment. Many examples online don’t go beyond a “Hello World” integration using the Purdue course API. Fortunately, we have investigated Virtual Entities for a few  of our clients and wanted to share our discoveries as to the limitations and benefits.

OData Overview

Virtual Entities (VEs) operate by connecting to any external data source that provides a publicly accessible OData API. We typically suggest VEs when the following requirements are in place:

  • Data cannot live in the CRM due to security reasons
  • Spending limits exist on CRM storage
  • Handling data in two different places will create unnecessary overhead
  • Data is read-only

Prior to moving forward, consult the following pros/cons list:


  1. Can read data from external source in real-time.
  2. No storage required in CRM. (except metadata)
  3. Can have relationships.
  4. Can appear in subgrids.
  5. Can be exported to Excel.
  6. Can be used with Advanced Find.
  7. Works with JavaScript on Forms and can make async calls to other Virtual Entities.
  8. Can be used with Global Search.
  9. Can be retrieved via SSIS.
  10. Requires minimal SSIS sync integration.


  1. Data is read only.
  2. Organization owned. No user-level security.
  3. Auditing and change tracking not supported.
  4. Cannot be converted to non-virtual entity.
  5. Cannot contain calculated or roll-up fields.
  6. Cannot display relational entity columns in views nor SSRS beyond lookup. (no joins)
  7. Non queue-enabled.
  8. No offline caching.
  9. Cannot be an Activity.
  10. Cannot have Business Process Flows.
  11. Must have a GUID in source table.
  12. Simple data types: Text, Number, Option Set, Date, Image, Lookup.
  13. Entities require a name field. For intersect entities this may require customization in SQL or enhanced custom OData.
  14. New feature means limited community support and the roadmap is unknown.

You can find the list above online, but here are 5 things we discovered that help us ascertain if Virtual Entities are truly the ideal solution:

1)    Displaying related columns is not supported

This limitation is a show stopper for many of our clients, which is why we bring it up first. You cannot display a related entity’s columns in a view. For instance, if a Course has a lookup to a Subject (Assuming Course, Subject or both are Virtual), you cannot display the Subject’s columns. As in, if a Subject has an abbreviation field and you wanted to see the Course’s Subject’s abbreviation, you cannot do it:



  • Name
  • Subject
    • Abbreviation (Field on Subject)

View Example

Introduction to Spanish
Abbreviation (Subject):

Since Course and Subject are two different entities, you cannot display the above, although if they were non-virtual entities this wouldn’t be a problem.

You CAN display the Course’s lookup field for Subject and at least derive the Subject’s name, but that’s due to the lookup technically living on the Course entity. What’s worse, the View builder alludes you can select these related columns, but if you do, you will receive a “Not Implemented” error.

 On a Course view navigate to Record Type Select ‘Subject’ and add its Abbreviation field to view You will receive an error

The “Not Implemented” error is unhelpful, but if you try to build this query via FetchXML and query using the SDK in Visual Studio, you’ll get a clearer error: ‘LinkEntity’ with ColumnSet not supported.

2) Relationships between Virtual and Non-Virtual Entities are allowed 😉

On the bright side, if you have a non-virtual entity (Professor) with a lookup to a virtual entity (Classroom), if Professor returns the right GUID for that Classroom ID, you can interact with it exactly as you would a regular entity. It will even appear in views using the Classroom’s Name field. (The same join limitations from above still apply).

3) JavaScript works on Virtual Entity Forms

Just like you use the Dynamics client-side SDK for your form JavaScript on non-virtual entities, the same API is available for VEs.

4) You can see the total row count in Views

When Dynamics makes an OData call, it appends the parameter &$count=true to the query to obtain the total row count. This feature is awesome because if a non-virtual entity has more than 5,000 records, the only total you get is the vague “5,000+”. However, with VEs you get the exact number:

5) Workflows are not supported, but there are workarounds

Custom Workflows are not supported with Virtual Entities, however, you can create a custom workflow activity and simply make a call to the OData API directly in your code. If you need help serializing the JSON in your OData call without using Newtonsoft and ILMerge, Scott Durow provides a native alternative.


It’s unclear what the roadmap is for Virtual Entities or if Microsoft will include the features that natively exist in OData (e.g. Joins). Nonetheless, the benefits Virtual Entities provide (e.g., easy integration with an OData API, savings on storage, storing data in one place) are the key reasons we offer them as a solution for our clients. If you’re interested in building an OData API with these Virtual Entities, we’ll be posting another blog titled 4 Tips for Building an OData API with Dynamics Virtual Entities on Thursday. Be sure to check it out!



Sean Astrakhan is an educator by training (and nature). He’s lived and taught in Michigan, Colombia and China, but is happy to call Baltimore “home.” Being an extrovert with penchants for adventure and overanalysis has led Sean to a career in technology consulting where he thrives on meeting new people and remedying their tech hardships.

When Sean isn’t coding or working with clients to make their lives easier, he’s getting schooled by Baltimore youth or falling on his face in adult gymnastics classes. But none of that bothers Sean because he never wants to stop learning and perfecting new skills. To paraphrase one of his favorite Beyoncé lyrics, “He grinds ‘til he owns it.”

If you need more Sean in your life, check out his burgeoning blog or, better yet, come work with him.