Reputation: 7628
What I am trying to do,
// get members from SharePoint list (can be null)
// get members from database (can be null)
// merge database members with sharepoint list members BUT only database members should have property VIP = true
// by merge I mean if they are not in list then add them to list, if they are in list then just change there property VIP = true
// by default VIP property is false
What I have developed so far,
List<Member> Members = new List<Member>();
foreach (SPListItem mItem in GetList(Url).Items)
{
Member m = new Member();
m.ID = mItem.ID;
m.Name = mItem.Title;
m.Company = Utilities.ObjectToStringOrEmpty(mItem[companyCol]);
m.eMail = Utilities.ObjectToStringOrEmpty(mItem[emailCol]);
m.Comment = Utilities.ObjectToStringOrEmpty(mItem[commentCol]);
m.Membership = Utilities.ObjectToStringOrEmpty(mItem[msCol]);
Members.Add(m);
}
var cd = new MemberManager().GetMoreMembers(Url + "/");
var activeMembers = cd.Where(am => am.MembershipStatus == "Active" || am.MembershipStatus == "Pending").ToList();
if (activeMembers != null || activeMembers.Count() > 0)
{
foreach (var am in activeMembers)
{
if (!Members.Any(a => a.eMail.ToLowerInvariant() == am.Email.ToLowerInvariant()))
{
Member m = new Member();
m.Name = am.FirstName + " " + am.LastName;
m.eMail = am.Email;
m.IsVip = true;
Members.Add(m);
}
}
}
md.Members = Members.ToArray();
Problem
Can I use Linq and merge these lists in a single go ? Maybe something like this, pseudo would be
var dbMembers = //GetDBMembers that are active or pending
var spMembers =
Select all members using `.Cast<SPListItem>()`
If spMembers has any dbMember (compared by email)
Then change that spMembers VIP property to true (which is by default false)
For rest dbMembers that doesn't exists in spMembers, add them with VIP property = true
Not sure how can i efficiently put above pseudo code into linq
Upvotes: 2
Views: 82
Reputation: 162
Try this:
var allSpMembers = GetSpList(); // get your members as you mentioned before by `.Cast<SPListItem>()`
List<SPListItem> spMembers =
dbMembers.GroupJoin(allSpMembers, dbM => dbM.Email, spM => spM.Email,
(dbMember, spMember) => new { dbMember, spMember })
.SelectMany(x => x.spMember.DefaultIfEmpty(), (x, spMember) =>
{
SPListItem yourSpListItem;
if (spMember != null)
{
yourSpListItem = spMember;
}
else
{
yourSpListItem = x.dbMember; //make some mapping here to SPListItem model
}
yourSpListItem.VIP = true;
return yourSpListItem;
}).ToList();
Upvotes: 1
Reputation: 36310
Yes you can. Use the Enumerable.Conca
t method to concatenate two lists into one.
If you split out the code to create Member objects into two methods, one MemberFromSpListItem
and one MemberFromActiveMember
then you will get the following relatively nice code:
var cd = new MemberManager().GetMoreMembers(Url + "/");
var activeMembers = cd.Where(am => am.MembershipStatus == "Active" || am.MembershipStatus == "Pending").ToList();
var members = GetList(Url)
.Items
.Select(MemberFromSpListItem)
.Concat(activeMembers.Select(MemberFromActiveMember))
.ToList();
Upvotes: 0