1

Usually for retrieve information from list without system fields we've use code like this:

clientContext.Load(logWorkItems,
  items => items.Include(
   item => item["Hours_x0020_spent"],
   item => item["Issue"],
   item => item["Date"]));

but now I have a lot of lists and I think its not good to write for each list it's own included fields one by one. Maybe it would be better to write flexible code for any list, but each of my ideas is't work.

Before loading collection of list items I'm loading list by title:

var list = context.Web.Lists.GetByTitle(listTitle);
context.Load(list);
context.ExecuteQuery();

May be there is a way to use collection list.Fields for retrieving all field titles to some List<string>, exclude from this list all of the system fields titles, and after that do some magic and include each non-system title to context.Load method?

Thank you in advance

  • Is this for Mobile and loading >100.000 items? – Danny '365CSI' Engelman Mar 1 '16 at 13:27
  • No, it's for MVC-website and < 1.000 items – John Doe Mar 1 '16 at 13:29
  • SharePoint adds a sh*tload of code so those extra fields won't make a difference in loading time – Danny '365CSI' Engelman Mar 1 '16 at 14:51
  • Yes, but because of any of system fields will be excluded we will manage only those data that we need. It would be easier to other developers to support this code, as I think... – John Doe Mar 1 '16 at 20:56
2

I've solved this problem by creating an array of expressions that I will include:

public static Expression<Func<ListItem, object>>[] ExcludeSystemFieldsExpressions(FieldCollection fields)
{
    var expressionsList = new List<Expression<Func<ListItem, object>>>();

    foreach (var item in fields)
    {
        var internalName = item.InternalName;
        if(!systemFieldsTitles.Contains(internalName))
            expressionsList.Add(x => x[internalName]);
    }
    return expressionsList.ToArray();
}

and whole code that will retrieve all fields without system fields:

var list = context.Web.Lists.GetByTitle(listTitle);
var fields = list.Fields;
context.Load(list);
context.Load(fields);
context.ExecuteQuery();

var listItems = list.GetItems(new CamlQuery { ViewXml = camlQuery });
var expressions = ExcludeSystemFieldsExpressions(fields);
context.Load(listItems, items => items.Include(expressions));
context.ExecuteQuery();

As Danny Engelman mentioned before this process doesn't affect perfomance, but when you will get your collection there won't be any of system fields, so it will be easier to manage this list for other developers and manipulate only data that we need, excluding other one.

P.S. systemFieldsTitles it's a List<string> that includes internal names of system fields, I've published source code of this list here: https://gist.github.com/reslea/564552907fca514ce61d

1
var systemFieldsIds = typeof(SPBuiltInFieldId).GetFields().Select(it => (Guid)it.GetValue(null)).ToArray();
var non_system_fields = list.Fields.Cast<SPField>().Where(it => systemFieldsIds.Contains(it.Id) == false).ToArray();
  • Can you please add some brief description about the code. – Asad Refai Oct 7 '16 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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