0

How get a display/description enum in LINQ query?

For example

 var query = dbo.Records.AsQueryable()
              .Select(x => new
              {
                  Id = x.Id,
                  Care = new
                  {
                      x.StartDate,
                      x.ForwardedBy,
                  },
                  Prescriptions = x.Prescriptions.Select(p => new
                  {
                      p.Medicament,
                      p.IntervalUse //My Enum, how get Display name?
                  }),
              }).OrderByDescending(x => x.Id);

This query is an exampleand I need to be AsQueryable to generate faster query in my database

7
  • Any reason you can't just keep it as the enum and get the display name in your view or in your form? That would, generally, be the preferred method. Commented Jul 27, 2016 at 21:42
  • 1
    What do you mean Display/description? do you have [DisplayNameAttribute]s on your enum, or are you talking about the enum's name Commented Jul 27, 2016 at 21:44
  • @JoshK I'm return to json Commented Jul 27, 2016 at 21:53
  • @SamIam Yes, i use DisplayNameAttribute and i can get DisplayName value in Linq query Commented Jul 27, 2016 at 21:53
  • Can't you just do a tostring that should return the name of the that enum value as a string? p.IntervalUse.ToString() Commented Jul 27, 2016 at 22:00

4 Answers 4

1

It may not be a bad idea to write an enum extension method if it's something you're going to need often :

public static string Describe(this Enum enumVal)
{
    var type = enumVal.GetType();
    var memInfo = type.GetMember(enumVal.ToString());
    var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
    return (attributes.Length > 0) ? ((DescriptionAttribute)(attributes[0])).Description : enumVal.ToString();
}
Sign up to request clarification or add additional context in comments.

Comments

1

Since LINQ doesn't know about that extension method, you will have to enumerate first, then get the attribute using reflection.

public static class EnumExtensions
{
    public static string GetDisplayName(this Enum value)
    {
        var attribute = (DisplayNameAttribute) value.GetType()
            .GetField(value.ToString())
            .GetCustomAttributes(false)
            .Where(a => a is DisplayNameAttribute)
            .FirstOrDefault();

        return attribute != null ? attribute.DisplayName : value.ToString();
    }
}

I can't test this right now, but you may try this and let us know if it works:

var query = dbo.Records.Include(x => x.Prescriptions).OrderByDescending(x => x.Id).AsEnumerable()
            .Select(x => new
            {
                Id = x.Id,
                Care = new
                {
                    x.StartDate,
                    x.ForwardedBy,
                },
                Prescriptions = x.Prescriptions.Select(p => new
                {
                    p.Medicament,
                    p.IntervalUse.GetDisplayName()
                }),
            });

6 Comments

How I use in LINQ query ?
You can't use it in a LINQ query unless you have already enumerated the IQueryable because there is no mapping in LINQ to Entities for this.
Wtf? why ef have enum support, if not have support a linq enum? :|
It has enum support, but it doesn't know anything about the attributes you have on the enum or enum values, so it cannot map the extension method I provided to SQL or whatever back end you are using.
Other solution Josh? I can generate my sql query for faster query, use ToList() or AsEnumerable is slow
|
0

I'd use the System.Reflection libraries.

public static GetMyEnumDisplayName(MyEnumType value)
{
    var displayAttribute = value.GetType()
        .GetTypeInfo()
        .GetDeclaredField(result)
        .GetCustomAttribute(typeof(DisplayAttribute));

        if (displayAttribute != null)
        {
            var Name = ((DisplayAttribute)displayAttribute).Name;
        }
}

That's not supported in linq to entities, but you can instead make that a helper property in your view model.

Your first step is to select a view model instead of an anonymous object the next step is to add a function in the setter

public string EnumDisplayValue { get { return GetMyEnumDisplayName(MyEnumValue); } } 

3 Comments

How i use in linq query?
@user98498 make that code into a method and call that method from the linq query
@user98498 what's happening?
0

why you do not go for the simplest way:

public enum IntervalUse
    {
        Hourly,
        Daily,
        Weekly
    }

    public static class EnumExt
    {
        public static string GetDescription(this IntervalUse item)
        {
            switch (item)
            {
                case IntervalUse.Hourly:
                    return "Hour by hour";
                case IntervalUse.Daily:
                    return "Day by day";
                case IntervalUse.Weekly:
                    return "Each week ...";
                default:
                    throw new ArgumentOutOfRangeException(nameof(item), item, null);
            }
        }
    }

then you can call in your query : p.IntervalUse.GetDescription()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.