将2个不同对象列表合并到不同类型的第三个列表中?

时间:2016-01-04 22:17:17

标签: c# linq

我为第三方API构建API包装器,将其对象转换为可用于其他处理的业务域对象。在这种情况下,我需要使用2个不同的对象ContactUser并将它们合并到一个名为UserContacts的对象列表中。我根据Email属性匹配这些对象,如果没有匹配的元素,则会插入一个新对象。

以下是我目前的对象和方法,我只想弄清楚是否有更好/更快的方法。

public class ContactUser : IUser
{
    public string SalesForceUserId { get; set; }
    public string SalesForceContactId { get; set; }
    public string ZendeskId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

private List<IUser> MergeContactsAndUsers()
{
    var sfContacts = SalesForceCache.Contacts.Data;
    var sfUsers = SalesForceCache.Users.Data;

    var newUsers = sfUsers.Select(user => new ContactUser
    {
        SalesForceUserId = user.Id, 
        Name = user.Name, 
        FirstName = user.FirstName, 
        LastName = user.LastName, 
        Email = user.Email
    }).Cast<IUser>().ToList();

    foreach (var contact in sfContacts)
    {
        var tmp = newUsers.FirstOrDefault(n => n.Email == contact.Email);
        if (tmp != null)
        {
            tmp.SalesForceContactId = contact.Id;
        }
        else
        {
            var newUser = new ContactUser
            {
                SalesForceContactId = contact.Id,
                Name = contact.Name,
                FirstName = contact.FirstName,
                LastName = contact.LastName,
                Email = contact.Email
            };

            newUsers.Add(newUser);
        }
    }

    return newUsers;
}

1 个答案:

答案 0 :(得分:1)

如果您想用Join替换当前的实现,可以使用以下内容:

private List<IUser> MergeContactsAndUsers()
{
    var sfContacts = SalesForceCache.Contacts.Data;
    var sfUsers = SalesForceCache.Users.Data;

    var leftJoinResults =
            sfUsers.Join(
                sfContacts,
                u => u.Email,
                c => c.Email,
                (u, c) => new ContactUser()
                {
                    SalesForceContactId = c.SalesForceContactId,
                    SalesForceUserId = u.Id,
                    Name = u.Name,
                    FirstName = u.FirstName,
                    LastName = u.LastName,
                    Email = u.Email
                }).Cast<IUser>().ToList();

    var rightJoinResults =
        sfContacts
            .Where(c => !leftJoinResults.Select(nu => nu.SalesForceContactId).Contains(c.Id))
            .Select(c => new ContactUser
            {
                SalesForceContactId = c.Id,
                Name = c.Name,
                FirstName = c.FirstName,
                LastName = c.LastName,
                Email = c.Email
            });

    leftJoinResults.AddRange(rightJoinResults);
    return leftJoinResults;
}

但由于Join只是一个左连接(并且您还需要右连接),因此仍然需要一个额外的查询来获取丢失的联系人(查询以获取rightJoinResults)。

它是使用Join的替代实现。如果没有适当的测量,很难判断它是否更快。