简体   繁体   English

Linq离开了联接,在哪里

[英]Linq left join and where

i'm learning the book:

LINQ to Objects Using C# 4.0 LINQ到使用C#4.0的对象

Ok, my question: 好吧,我的问题:

I have two class: Contact and CallLog . 我有两个类: ContactCallLog It look like: 看起来像:

public class Contact
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public DateTime DateOfBirth { get; set; }
        public string State { get; set; }
};

public class CallLog
    {
        public string Number { get; set; }
        public int Duration { get; set; }
        public bool Incoming { get; set; }
        public DateTime When { get; set; }
    }

Relation: Contact.Phone equals CallLog.Number 关系: Contact.Phone等于CallLog.Number

Two Class have method: SampleData(). 两个类具有方法:SampleData()。 This metod return a simple List<> with Contacts and CallLogs. 此方法返回一个带有联系人和CallLogs的简单List <>。

List<Contact> contacts = Contact.SampleData();
List<CallLog> callLogs = CallLog.SampleData();

My query is: how many calls do each contact. 我的查询是:每个联系人要打多少个电话。

var query2 = (from contact in contacts
                         join callLog in callLogs on contact.Phone equals callLog.Number into joined
                         from callLog in joined.Where(p=>p.Incoming == false).DefaultIfEmpty()

                         select new
                         {
                             who = contact.FirstName + " " + contact.LastName + " " + contact.Phone,
                             how_many = callLog != null ? callLogs.Where(s =>s.Number == contact.Phone).Count() : 0
                         }).Select(p=>p).Distinct();
            foreach (var q in query2)
            {
                Console.WriteLine(q.who + " " + q.how_many);
            }

the result: 结果:

Tom XXXX 555-555-555 calls 2 times Tom XXXX 555-555-555通话2次

Sophie YYYY 333-333-333 calls 3 times 苏菲YYYY 333-333-333通话3次

Mark ZZZZ 111-111-111 calls 0 times 标记ZZZZ 111-111-111通话0次

Now i want to choose only callLog where Incoming == true: 现在我只选择传入== true的callLog:

var query2 = (from contact in contacts
                         join callLog in callLogs.Where(p=>p.Incomming == true) on contact.Phone equals callLog.Number into joined
                         from callLog in joined.Where(p=>p.Incoming == false).DefaultIfEmpty()

                         select new
                         {
                             who = contact.FirstName + " " + contact.LastName + " " + contact.Phone,
                             how_many = callLog != null ? callLogs.Where(s =>s.Number == contact.Phone).Count() : 0
                         }).Select(p=>p).Distinct();
            foreach (var q in query2)
            {
                Console.WriteLine(q.who + " " + q.how_many);
            }

(look at the second line in new query2) but result is same: (请查看新query2的第二行),但结果相同:

Tom XXXX 555-555-555 calls 2 times Tom XXXX 555-555-555通话2次

Sophie YYYY 333-333-333 calls 3 times 苏菲YYYY 333-333-333通话3次

Mark ZZZZ 111-111-111 calls 0 times 标记ZZZZ 111-111-111通话0次

how could i fix it? 我该如何解决?

Try this : 尝试这个 :

  var query2 = (from contact in contacts
                                 join callLog in callLogs on contact.Phone equals callLog.Number into joined
                                 from callLog in joined.Where(p=>p.Incoming == true).DefaultIfEmpty()

                                 select new
                                 {
                                     who = contact.FirstName + " " + contact.LastName + " " + contact.Phone,
                                     how_many = callLog != null ? callLogs.Where(s =>s.Number == contact.Phone).Count() : 0
                                 }).Select(p=>p).Distinct();
foreach (var q in query2)
{
  Console.WriteLine(q.who + " " + q.how_many);
}

Looking at the problem instead of the code, I think the following better expresses what you're trying to do: 考虑问题而不是代码,我认为以下内容可以更好地表达您要执行的操作:

var contacts = new List<Contact>
{
    new Contact { FirstName = "Tom", LastName = "Jones", Phone = "555-555-555" },
    new Contact { FirstName = "Sophie", LastName = "Monk", Phone = "333-333-333" },
    new Contact { FirstName = "Mark", LastName = "Twain", Phone = "111-111-111" }
};

var callLogs = new List<CallLog>
{
    new CallLog { Number = "555-555-555", Incoming = true },
    new CallLog { Number = "555-555-555", Incoming = true },
    new CallLog { Number = "333-333-333", Incoming = true },
    new CallLog { Number = "333-333-333", Incoming = true },
    new CallLog { Number = "333-333-333", Incoming = true }
};

var data = contacts.Select(c => new 
    {
        who = string.Format("{0} {1} {2}", c.FirstName, c.LastName, c.Phone),
        how_many = callLogs.Count(l => l.Number == c.Phone && l.Incoming)
    }).ToList();

data.Dump();

}

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string State { get; set; }
}

public class CallLog
{
    public string Number { get; set; }
    public int Duration { get; set; }
    public bool Incoming { get; set; }
    public DateTime When { get; set; }

Sample written in Linqpad, copy/paste it straight into the editor and you should see the following output: 用Linqpad编写的示例,直接将其复制/粘贴到编辑器中,您将看到以下输出:

  • who how_many 谁怎么样
  • Tom Jones 555-555-555 2 汤姆·琼斯555-555-555 2
  • Sophie Monk 333-333-333 3 苏菲和尚333-333-333 3
  • Mark Twain 111-111-111 0 马克·吐温111-111-111 0

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

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