Lately I am working a lot with LINQ and all flavors like LINQ to XML, LINQ to XSD, LINQ to objects, etc.
Today I had to build some functionality in SharePoint where I had to split users in two groups based on a profile property in their User Profile.
In this article I will show you how I did this.
The users I have to query are stored in a DataView (represented by the variable webUsers
) so that's my starting point. First, I have to create an instance of the UserProfileManager class. This is the connection with the User Profile Database.
Then I iterate the DataView
and Cast
every item to the row
variable. In the DataRowView
the AccountName
column contains a domain\user
value. Because it is an object
and I need it multiple times I store it in a locale variable using the let
keyword so I only have to cast it one time.
One of the great things is that you are allowed to combine multiple let
's and where
statements. So, every AccountName
that is null
or empty
will be filtered out.
If I would use the GetUserProfile method and pass an account which is not (yet) present in the profile database, this would result in an exception. That is why I first use a where
query in combination with the UserExists method.
For readability, I use another let
to store the value I need in the comparison. Now I can create an anonymous object with a boolean
if the title was equal to "student
", and some other profile properties.
var profileManager = new UserProfileManager(); var users = (from DataRowView row in webUsers let accountName = (string)row["AccountName"] where !string.IsNullOrEmpty(accountName) where profileManager.UserExists(accountName) let userProfile = profileManager.GetUserProfile(accountName) let title = (userProfile["Title"] != null) ? (string)userProfile["Title"].Value : string.Empty select new { IsStudent = title == "student", Initials = (userProfile["Initials"] != null) ? (string)userProfile["Initials"].Value : string.Empty, LastName = (userProfile["LastName"] != null) ? (string)userProfile["LastName"].Value : string.Empty, }).AsEnumerable(); var employees = from employee in users where !employee.IsStudent select employee; var students = from student in users where student.IsStudent select student;
Now, I can easily get all students and employees in different collections based on that boolean property. And never call the ProfileManager more than necessary.