Mathematics
Mathematics

Reputation: 7628

Can I merge these two lists in 1 go

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

Answers (2)

Dawid Pawłowski
Dawid Pawłowski

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

Rune Grimstad
Rune Grimstad

Reputation: 36310

Yes you can. Use the Enumerable.Concat 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

Related Questions