0

In the xConnect model, we have a property with dictionary type and when we try to put it in a lambda expression for some logic it fires back.

Sample Model:

public class eBikeContactFacet : Facet
{
    public DateTime NewsletterChangedOn { get; set; }
    public string SourceOfLead { get; set; }
    public string ContactType { get; set; }
    public Dictionary<string, eBikeTrainingFacet> Trainings { get; set; }
}

How we fetch:

var trainingContacts = client.Contacts.Where(c => c.GetFacet<eBikeContactFacet>() != null && c.GetFacet<eBikeContactFacet>().GlobalBoschID!=null).ToList();                        

It gives me an error System.AggregateException: One or more errors occurred. ---> Sitecore.XConnect.Schema.XdbModelException: Unsupported value type Sitecore.XConnect.Schema.XdbFacetType

Looks like Dictionary is not supported?

Did anyone face this before, kindly help.

2 Answers 2

1

Dictionary properties are alllowed. For example EmailAddress is a facet which has next definition:

namespace Sitecore.XConnect.Collection.Model
{
    /// <summary>
    /// Represents a list of email addresses for a <see cref="T:Sitecore.XConnect.Contact" />
    /// </summary>
    [FacetKey("Emails")]
    [Serializable]
    public class EmailAddressList : Facet
    {
        /// <summary>
        /// Default facet key for the EmailAddressList facet.
        /// </summary>
        public const string DefaultFacetKey = "Emails";

        /// <summary>
        /// Gets or sets the alternative email addresses for this contact different than the preferred one. The key defines the identifier for that email address. Examples are "work", "home", or "personal".
        /// </summary>
        /// <value>
        /// The entries.
        /// </value>
        public Dictionary<string, EmailAddress> Others
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the key related to the preferred address.
        /// </summary>
        /// <value>
        /// The preferred key.
        /// </value>
        public string PreferredKey
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the preferred email for the contact.
        /// </summary>
        /// <value>
        /// The preferred email.
        /// </value>
        public EmailAddress PreferredEmail
        {
            get;
            set;
        }

Did you deploy your custom model into xConnect ? Does eBikeTrainingFacet class have Serializable Attribute ?

Did you specify your custom facet to be returned with a contact or batch of contacts by passing an array of facet keys into the ContactExpandOptions? like on below example?

var contacts = await client.GetAsync<Contact>(references, new Sitecore.XConnect.ContactExpandOptions(EmailAddressList.DefaultFacetKey, AddressList.DefaultFacetKey));
4
  • HI Vlad, Yes, the model is deployed and also have serializable for eBikeContactData and eBikeTrainingFacet class. Thanks for the answer, but GetAsync works for single contact where we pass the Identifier in the references. What if we have to get all the contacts , like in a pipeline
    – Sujana
    Commented Mar 27, 2019 at 11:08
  • citizensitecore.com/2017/10/17/… have a look here , they use ContactExpandOptions in the same way Commented Mar 27, 2019 at 11:41
  • Is there any difference how we fetch it? Because the way I fetch gives an error var trainingContacts = client.Contacts.WithExpandOptions(new ContactExpandOptions(StringConstants.LoginDynamicCrmFacetName)).ToList(); foreach (var contact in trainingContacts.Result) { var contactFacet = contact.GetFacet<eBikeContactFacet>(StringConstants.LoginDynamicCrmFacetName); gives an error : The specified type does not match the facet at Sitecore.XConnect.Entity.GetFacet[TFacet](String name)
    – Sujana
    Commented Mar 27, 2019 at 13:08
  • you need to add your facet key to ContactExpandOptions. if you don't add FacetKey you can not use it on Where method. Commented Mar 27, 2019 at 13:11
1

I know this question has already got an accepted answer, but I recently had the same issue and the solution was a bit different. Note, this only applies if you're using Azure Search for your xDB index.

According to Sitecore's documentation, there are certain methods that aren't supported. In particular:

It is currently not possible to check if a facet is null. For example:

var notWebVisits = client.Interactions.Where(c => c.WebVisit() == null);

My code was similar to yours, where I was checking that the facet existed before looking within it (c => c.GetFacet<eBikeContactFacet>() != null in your example). I found that you don't need to check if the facet is null when doing a search. If we had an actual list of items in memory, checking for null first would avoid exceptions, but since this translates into a search query, it's not needed.

However, I'm not sure how you'd check for your GlobalBoschID value. If it's an integer, you could check to see if it's greater than 0, but if it's a string or a GUID then I'm not sure. The documentation outlines the limitations of searching against different variable types (Note, 9.0.1 and 9.0.2 support different methods).

Oh, and one last thing - I've sometimes run into problems when using Contact.GetFacet<>() without specifying the facet key. Does it help if you use c.GetFacet<eBikeContactFacet>(eBikeContactFacet.DefaultFacetKey)?

2
  • 1
    Comparing the full instance returned by GetFacet to anything (null) in this case is precisely why the error message triggers. Comparing null values to simple fields like an Id is ok.
    – eglasius
    Commented Jul 18, 2019 at 17:01
  • You are a lifesaver! Commented Nov 16, 2023 at 21:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.