Linq to object右外连接

时间:2013-07-09 09:56:45

标签: c# linq

我已经编写了以下linq查询,但我没有得到预期的结果。我的预期结果是lst和list之间的所有匹配记录以及列表中的所有非匹配记录  例如。

我想要以下结果

A,B,C,d,E,F

public class Com : IEqualityComparer<DuplicateData>
    {
        public bool Equals(DuplicateData x, DuplicateData y)
        {
            return x.address.Equals(y.address);
        }

        public int GetHashCode(DuplicateData obj)
        {
            return obj.address.GetHashCode();

        }
    }

static void Run ()
{
    List<string> lst = new List<string>();
    lst.Add("a");
    lst.Add("b");
    lst.Add("c");
    lst.Add("p");

    List<DuplicateData> list = new List<DuplicateData>()
    {
        new DuplicateData{address="a"},
        new DuplicateData{address="a"},
        new DuplicateData{address="a"},
        new DuplicateData{address="b"},
        new DuplicateData{address="b"},
        new DuplicateData{address="c"},
        new DuplicateData{address="d"},
        new DuplicateData{address="e"},
        new DuplicateData{address="f"},
    };

    var dup = list.Distinct(new Com());
    var RightJoin = from x in dup
                    join y in lst
                    on x.address equals y
                    into right
                    from z in right
                    select new
                    {
                        UniqueAddress = z,

                    };

}

2 个答案:

答案 0 :(得分:2)

试试这样:

var RightJoin = from x in dup
                join y in lst
                on x.address equals y
                into right
                from z in right.DefaultIfEmpty(x.address)
                select new
                {
                    UniqueAddress = z,
                };

结果是(a,b,c,d,e,f)

工作样本:http://ideone.com/MOIhZH


<强>解释

要在linq中进行左/右连接,必须使用DefaultIfEmpty方法,当没有匹配时(联接结果为空)将产生(默认)结果。但是,字符串的默认值为null,因此您必须从“左侧”集合中提供默认值,以便在结果集中查看它。


替代方法

这可能是更方便的方法。您可以从z - 联接的左侧进行选择,而不是从x.address中选择并提供默认值。

var RightJoin = from x in dup
                join y in lst
                on x.address equals y
                into right
                from z in right.DefaultIfEmpty()
                select new
                {
                    UniqueAddress = x.address,
                };

答案 1 :(得分:0)

这应该有效:

var res = from x in list
          join y in lst on x.address equals y into right 
          from xy in right.DefaultIfEmpty()
          select new { UniqueAddress = xy };

结果:

{ UniqueAddress = a },
{ UniqueAddress = a },
{ UniqueAddress = a },
{ UniqueAddress = b },
{ UniqueAddress = b },
{ UniqueAddress = c },
{ UniqueAddress = null },
{ UniqueAddress = null },
{ UniqueAddress = null }