LINQ到实体 - 根据联接,条件和分类获得结果

发布于 2025-01-22 15:55:06 字数 2376 浏览 2 评论 0原文

我有一些代码可以通过3个单独列表的记录进行循环,并执行逻辑以创建一个新对象。它有效,但需要很长时间。我希望我可以将其全部简化为LINQ到实体查询。

本质上,我有一个人列表和电话号码列表。电话号码具有类型(“单元”,“家庭”,“办公室”)和等级(1-x)。如果某人有两个手机,那么等级应优先。

结果集应只有一个单元格(排名最低)和一个家庭电话(排名最低)。如果没有牢房或家庭电话,则应为null。

Person person1 = new("Person", "One");
Person person2 = new("Person", "Two");
Person person3 = new("Person", "Three");
Person person4 = new("Person", "Four");
Person person5 = new("Person", "Five");

Phone ph1 = new("1112222222", "home", 2, person1);
Phone ph2 = new("1111111111", "cell", 1, person1);
Phone ph3 = new("2223331111", "cell", 1, person2);
Phone ph4 = new("3334441111", "cell", 1, person3);
Phone ph5 = new("3335552222", "cell", 2, person3);
Phone ph6 = new("4446662222", "home", 2, person4);
Phone ph7 = new("5557772222", "cell", 3, person5);
Phone ph8 = new("5557773333", "home", 2, person5);

// Create two lists.
List<Person> people = new() { person1, person2, person3, person4, person5 };
List<Phone> phones = new() { ph1, ph2, ph3, ph4, ph5, ph6, ph7, ph8 };

***//CAN A LINQ to ENTITIES QUERY PRODUCE THE DESIRED RESULTS
var query =
    from person in people
    join ph in phones on person equals ph.Owner into persPh
    from personPhones in persPh.DefaultIfEmpty()
    select new PersonPhone
    {
        FirstName = person.FirstName,
        LastName = person.LastName,
        CellPhoneNumber = personPhones?.Number ?? string.Empty, //<==== Needs to be lowest ranking number of type = "cell"
        HomePhoneNumber = personPhones?.Number ?? string.Empty  //<==== Needs to be lowest ranking number of type = "home"
    };***

foreach (PersonPhone v in query)
{
    Console.WriteLine($"{v.FirstName + " " + v.LastName + ":",-15} {v.CellPhoneNumber,-15} {v.HomePhoneNumber,-15} ");
}
// This code Should produce the following output:
//
// Person One:    1111111111    1112222222
// Person Two:    2223331111
// Person Three:  3334441111    
// Person Four:                 4446662222    
// Person Five:   5557772222    5557773333


public record class Person(string FirstName, string LastName);
public record class Phone(string Number, string Type, int Rank, Person Owner);
public record class PersonPhone(string FirstName, string LastName, string CellPhoneNumber, string HomePhoneNumber);

I have some code that loops through records of 3 separate lists and performs logic to create a new object. It works but takes a very long time. I'm hoping I can simplify it all into a LINQ to Entities query.

Essentially, I have a list of People, and a List of Phone Numbers. The Phone numbers have a type ('cell', 'home', 'office', etc.) and a rank (1-x). If someone has two cell phones the the lower the rank should take priority.

The result set should have only one cell (the lowest ranking) and one home phone (the lowest ranking). These should be null if there is no cell or home phone.

Person person1 = new("Person", "One");
Person person2 = new("Person", "Two");
Person person3 = new("Person", "Three");
Person person4 = new("Person", "Four");
Person person5 = new("Person", "Five");

Phone ph1 = new("1112222222", "home", 2, person1);
Phone ph2 = new("1111111111", "cell", 1, person1);
Phone ph3 = new("2223331111", "cell", 1, person2);
Phone ph4 = new("3334441111", "cell", 1, person3);
Phone ph5 = new("3335552222", "cell", 2, person3);
Phone ph6 = new("4446662222", "home", 2, person4);
Phone ph7 = new("5557772222", "cell", 3, person5);
Phone ph8 = new("5557773333", "home", 2, person5);

// Create two lists.
List<Person> people = new() { person1, person2, person3, person4, person5 };
List<Phone> phones = new() { ph1, ph2, ph3, ph4, ph5, ph6, ph7, ph8 };

***//CAN A LINQ to ENTITIES QUERY PRODUCE THE DESIRED RESULTS
var query =
    from person in people
    join ph in phones on person equals ph.Owner into persPh
    from personPhones in persPh.DefaultIfEmpty()
    select new PersonPhone
    {
        FirstName = person.FirstName,
        LastName = person.LastName,
        CellPhoneNumber = personPhones?.Number ?? string.Empty, //<==== Needs to be lowest ranking number of type = "cell"
        HomePhoneNumber = personPhones?.Number ?? string.Empty  //<==== Needs to be lowest ranking number of type = "home"
    };***

foreach (PersonPhone v in query)
{
    Console.WriteLine(
quot;{v.FirstName + " " + v.LastName + ":",-15} {v.CellPhoneNumber,-15} {v.HomePhoneNumber,-15} ");
}
// This code Should produce the following output:
//
// Person One:    1111111111    1112222222
// Person Two:    2223331111
// Person Three:  3334441111    
// Person Four:                 4446662222    
// Person Five:   5557772222    5557773333


public record class Person(string FirstName, string LastName);
public record class Phone(string Number, string Type, int Rank, Person Owner);
public record class PersonPhone(string FirstName, string LastName, string CellPhoneNumber, string HomePhoneNumber);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彡翼 2025-01-29 15:55:06

尝试使用Linq。我给了您2个使用linqpad

void Main()
{
    Person person1 = new("Person", "One");
    Person person2 = new("Person", "Two");
    Person person3 = new("Person", "Three");
    Person person4 = new("Person", "Four");
    Person person5 = new("Person", "Five");

    Phone ph1 = new("1112222222", "home", 2, person1);
    Phone ph2 = new("1111111111", "cell", 1, person1);
    Phone ph3 = new("2223331111", "cell", 1, person2);
    Phone ph4 = new("3334441111", "cell", 1, person3);
    Phone ph5 = new("3335552222", "cell", 2, person3);
    Phone ph6 = new("4446662222", "home", 2, person4);
    Phone ph7 = new("5557772222", "cell", 3, person5);
    Phone ph8 = new("5557773333", "home", 2, person5);

    // Create two lists.
    List<Person> people = new() { person1, person2, person3, person4, person5 };
    List<Phone> phones = new() { ph1, ph2, ph3, ph4, ph5, ph6, ph7, ph8 };
    
    var personPhoneList = new List<PersonPhone>();
    //option 1
    people.ForEach(person =>
    {
        var pp = new PersonPhone()
        {
            FirstName = person.FirstName,
            LastName = person.LastName,
            CellPhoneNumber = phones.FirstOrDefault(cp => cp.type == "cell" && cp.Owner == person)?.Number,
            HomePhoneNumber = phones.FirstOrDefault(cp => cp.type == "home" && cp.Owner == person)?.Number
        };
        personPhoneList.Add(pp);
    });
    personPhoneList.Select(v => new
    {
        v.FirstName,
        v.LastName,
        v.CellPhoneNumber,
        v.HomePhoneNumber
    }).Dump("Option 1");

    //option 2
    people.Select(person => new PersonPhone()
    {
        FirstName = person.FirstName,
        LastName = person.LastName,
        CellPhoneNumber = phones.OrderBy(o=> o.Rank).FirstOrDefault(cp => cp.type == "cell" && cp.Owner == person)?.Number,
        HomePhoneNumber = phones.OrderBy(o=> o.Rank).FirstOrDefault(cp => cp.type == "home" && cp.Owner == person)?.Number
    })
    .ToList().Dump("option 2");

    
    
}

public class PersonPhone
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string CellPhoneNumber { get; set; }
    public string HomePhoneNumber { get; set; }

}



public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Person(string _first, string _last)
    {
        FirstName = _first;
        LastName = _last;
    }
}
public class Phone
{
    public string Number { get; set; }
    public string type { get; set; }
    public int Rank { get; set; }
    public Person Owner { get; set; }

    public Phone(string _number, string _type, int _order, Person _person)
    {
        Number = _number;
        type = _type;
        Rank = _order;
        Owner = _person;
    }
}

”在此处输入图像描述”

try to use linq. i gave you 2 options for education using Linqpad

void Main()
{
    Person person1 = new("Person", "One");
    Person person2 = new("Person", "Two");
    Person person3 = new("Person", "Three");
    Person person4 = new("Person", "Four");
    Person person5 = new("Person", "Five");

    Phone ph1 = new("1112222222", "home", 2, person1);
    Phone ph2 = new("1111111111", "cell", 1, person1);
    Phone ph3 = new("2223331111", "cell", 1, person2);
    Phone ph4 = new("3334441111", "cell", 1, person3);
    Phone ph5 = new("3335552222", "cell", 2, person3);
    Phone ph6 = new("4446662222", "home", 2, person4);
    Phone ph7 = new("5557772222", "cell", 3, person5);
    Phone ph8 = new("5557773333", "home", 2, person5);

    // Create two lists.
    List<Person> people = new() { person1, person2, person3, person4, person5 };
    List<Phone> phones = new() { ph1, ph2, ph3, ph4, ph5, ph6, ph7, ph8 };
    
    var personPhoneList = new List<PersonPhone>();
    //option 1
    people.ForEach(person =>
    {
        var pp = new PersonPhone()
        {
            FirstName = person.FirstName,
            LastName = person.LastName,
            CellPhoneNumber = phones.FirstOrDefault(cp => cp.type == "cell" && cp.Owner == person)?.Number,
            HomePhoneNumber = phones.FirstOrDefault(cp => cp.type == "home" && cp.Owner == person)?.Number
        };
        personPhoneList.Add(pp);
    });
    personPhoneList.Select(v => new
    {
        v.FirstName,
        v.LastName,
        v.CellPhoneNumber,
        v.HomePhoneNumber
    }).Dump("Option 1");

    //option 2
    people.Select(person => new PersonPhone()
    {
        FirstName = person.FirstName,
        LastName = person.LastName,
        CellPhoneNumber = phones.OrderBy(o=> o.Rank).FirstOrDefault(cp => cp.type == "cell" && cp.Owner == person)?.Number,
        HomePhoneNumber = phones.OrderBy(o=> o.Rank).FirstOrDefault(cp => cp.type == "home" && cp.Owner == person)?.Number
    })
    .ToList().Dump("option 2");

    
    
}

public class PersonPhone
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string CellPhoneNumber { get; set; }
    public string HomePhoneNumber { get; set; }

}



public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Person(string _first, string _last)
    {
        FirstName = _first;
        LastName = _last;
    }
}
public class Phone
{
    public string Number { get; set; }
    public string type { get; set; }
    public int Rank { get; set; }
    public Person Owner { get; set; }

    public Phone(string _number, string _type, int _order, Person _person)
    {
        Number = _number;
        type = _type;
        Rank = _order;
        Owner = _person;
    }
}

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文