简体   繁体   English

Linq反对右外部联接

[英]Linq to object Right outer join

I have written following linq query but I am not getting expected result.My Expected result is all the matching record bettween lst and list and all the non matching record from list for example. 我写了以下linq查询,但是没有得到预期的结果。例如,我的预期结果是lst和list之间的所有匹配记录以及list中的所有不匹配记录。

I want following result 我想要以下结果

a,b,c,d,e,f 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,

                    };

}

Try it like this: 像这样尝试:

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,
                };

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

Working sample: http://ideone.com/MOIhZH 工作示例: http : //ideone.com/MOIhZH


Explanation 说明

To make a left/right join in linq you have to use DefaultIfEmpty method, that will yield (default) result when there is no match (the joined result is empty). 要在linq中进行左/右联接,您必须使用DefaultIfEmpty方法,该方法将在不匹配(联接结果为空)时产生(默认)结果。 However, default value for string is null so you have to provide default value from the "left side" collection to see it in the result set. 但是,字符串的默认值为null因此您必须提供“左侧”集合中的默认值才能在结果集中看到它。


Alternative approach 替代方法

This is probably more convenient approach. 这可能是更方便的方法。 Instead of selecting from z and providing the default value, you will select from x.address - the left side of the join. 您可以从x.address的左侧)中选择,而不是从z中选择并提供默认值。

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,
                };

This should work: 这应该工作:

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 };

result: 结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM