Skip to content

Support nullable type and enum conversions on queries. Fixed !! #15

@mediabuff

Description

@mediabuff
internal static class DocumentConverterExtensions
{

    /// <summary>
    /// Stores the properties of the generic object as text fields in a Lucene document.
    /// </summary>
    /// <param name="instance"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    internal static Document ConvertToDocument<T>(this T instance) where T : IDocument
    {
        var document = new Document();

        foreach (var property in typeof(T).GetProperties())
        {
            var value = property.GetValue(instance) ?? string.Empty;
            var fieldName = property.Name;
            var facetAttribute = System.Attribute.GetCustomAttribute(property, typeof(FacetProperty));

            if (!property.PropertyType.IsArray)
            {
                var enumValue = getEnumValue(property, instance);
                if (enumValue != null)
                    addField(document, fieldName, facetAttribute, enumValue);
                else
                    addField(document, fieldName, facetAttribute, value);
            }
            else
            {
                var array = (Array)value;
                foreach (var arrayItem in array)
                {
                    addField(document, fieldName, facetAttribute, arrayItem);
                }
            }
        }

        return document;
    }

    private static void addField(Document document, string fieldName, System.Attribute? facetAttribute, object fieldObj)
    {
        var fieldValue = fieldObj?.ToString() ?? string.Empty;

        document.Add(new TextField(fieldName, fieldValue, Field.Store.YES));

        if (facetAttribute != null)
        {
            document.Add(new FacetField(fieldName, fieldValue));
        }
    }

    private static string? getEnumValue(PropertyInfo property, object instance)
    {
        if (property != null)
        {
            Type typeToCheck = GetUnderlyingType(property);

            if (typeToCheck.IsEnum)
            {
                // Get the value of the property from the instance
                var enumValue = property.GetValue(instance);

                // Convert the enum value to its underlying numerical type (e.g., int or long)
                // Using Convert.ToInt64 is safe as it fits every enum underlying type
                long numericalValue = Convert.ToInt64(enumValue);
                return numericalValue.ToString();
            }
        }
        return null;
    }

    public static Type GetUnderlyingType(PropertyInfo propertyInfo)
    {
        // Get the underlying type, checking if it is a Nullable<T>
        var underlyingType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);

        // Determine the actual type to check IsEnum on (either the underlying type or the original type)
        var typeToCheck = underlyingType ?? propertyInfo.PropertyType;
        return typeToCheck;
    }

   ...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions