我可以合并这两个列表吗?

时间:2015-10-15 07:34:39

标签: c# linq

我想做什么,

// 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

到目前为止我已经开发了什么,

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();

问题

我可以使用Linq并一次合并这些列表吗?也许这样的事情,伪就是

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

不确定如何有效地将上述伪代码放入linq

2 个答案:

答案 0 :(得分:1)

试试这个:

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();

答案 1 :(得分:0)

是的,你可以。使用Enumerable.Concat method将两个列表连接成一个。

如果您将代码分割成两个方法,一个MemberFromSpListItem和一个MemberFromActiveMember,那么您将获得以下相对不错的代码:

    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();