Correct MultiChoice Values in LINQ to SharePoint Query

1.6k views Asked by At

I am using a LINQ to SharePoint query to return items from a SharePoint list.

var myOpenTasksQuery = from myTasks in tasks
                       where myTasks.TaskStatus != TaskStatus.Completed
                       select myTasks

However, the list I am querying, an OOTB Tasks list, there are a number of multi-choice fields (Status, Priority), which are translated into enumerations. In my query results, a task item status is returned as "_2Normal", and not as "(2) Normal" as I would expect. I see in the proxy file generated by SPMetal.exe that there is a ChoiceAttribute for the task status enumeration which contains the value I require:

public enum Priority : int {

    None = 0,

    Invalid = 1,

    [Microsoft.SharePoint.Linq.ChoiceAttribute(Value="(1) High")]
    _1High = 2,

    [Microsoft.SharePoint.Linq.ChoiceAttribute(Value="(2) Normal")]
    _2Normal = 4,

    [Microsoft.SharePoint.Linq.ChoiceAttribute(Value="(3) Low")]
    _3Low = 8,
}

How can I modify the query above to return the correct value?

Thanks, MagicAndi.

3

There are 3 answers

1
Jon Skeet On BEST ANSWER

Surely the task item status is being returned as a value of type Priority - not a string at all. If you want to display that, I'd expect you to have to convert it into a string appropriately (possibly using some helper methods which take note of the attribute applied to some values).

Just calling ToString() on an enum value will return the name of the value if it has one, or a string representation of the number otherwise. It won't care about ChoiceAttribute. I suspect that's what's happening here.

0
Kornelis On

Remember that querying a choicefield, as generated by SPMetal by default, will not be translated to CAML and thus your tasks-list will first be completely loaded to memory, and queried afterwards.

This, in short, means that as (and if) your tasks-list grows in time, performance of the query will drop equally.

I have, so far, not found a solution to it yet (struggling with it).

0
p.campbell On

Try using this extension method to get the actual string value of your enum.

foreach (var o in  myOpenTasksQuery)
{
    Console.WriteLine(o.Priority.StringValueOf());
}



public static class Extensions
{
    public static string StringValueOf(this Enum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());
        Microsoft.SharePoint.Linq.ChoiceAttribute[] attributes =
            (Microsoft.SharePoint.Linq.ChoiceAttribute[])fi.GetCustomAttributes(
            typeof(Microsoft.SharePoint.Linq.ChoiceAttribute), false);
        if (attributes.Length > 0)
        {
            return attributes[0].Value;
        }
        else
        {
            return value.ToString();
        }
    }
}