将两个不同类型的列表匹配在一起

时间:2013-01-11 17:20:23

标签: c# linq entity-framework

我有两个表,每个表都有自己的模型......

    class FamilyMan
    { 
        public int family_ID {get; set;}

        public string name {get; set;}
        public string fav_color {get; set;}
    }

    class BusinessMan
    {
        public int work_ID {get; set;}

        public string name {get; set;}
        public string fav_color {get; set;}

        //unrelated data etc
        public string job_title {get; set;}
    }

...我希望能够根据namefav_color将所有FamilyMans匹配到匹配的BusinessMans。

我目前有类似的东西:

    //fill lists from database
    var family_list = dbContext.FamilyMen.ToList();
    var busy_list = dbContext.BusinessMen.ToList();
    //create empty dict for matching the two types
    var matches = new Dict<FamilyMan, BusinessMan>();


    foreach (FamilyMan fam_man in family_list) {
        foreach (BusinessMan busy_man in busy_list) {
            //if both names and colors match, consider them a matching
            //object and add them each to the dict
            if (fam_man.name == busy_man.name &&
                    fam_man.color == busy_man.color) {
                matches_MtO[fam_man] = busy_man;
            }
        }
    }

但是需要很长时间才能完成。

我还查看了使用foreach循环遍历一个列表,然后使用LINQs FirstOrDefault来匹配它们,但效率似乎大致相同。

是否有更好的方法将FamilyManBusinessMan匹配在一起?

3 个答案:

答案 0 :(得分:4)

像这样的linq查询会更快:

var matches = (
    from f in family_list
    join b in busy_list
    on f.color == b.color
    && f.name == b.name
    select new {f, b}
);

答案 1 :(得分:3)

您应该使用LINQ的连接语法。这将使后端数据库能够进行匹配,并仅返回结果。

要在复合键上启用联接,请按照MSDN guidance here.

进行操作
var query = from fm in dbContext.FamilyMen
            join bm in dbContext.BusinessMen on 
                new { bm.name, bm.color } equals new { fm.name, fm.color }
            select new {
               FamilyMan = fm,
               BusinessMan = bm
            };

var resultList = query.ToList();

答案 2 :(得分:2)

你正在遍历两个列表,即O(N平方)。

匹配项目后,不必再次匹配。您可以从列表中删除匹配的项目,减少不必要的比较。

更好的是,由于您匹配两个相同的属性,您可以使用表示组合属性作为键的哈希来构建字典。然后你可以循环遍历family_list_dictionary的键,只需在busy_list_dictionary中查找匹配的键。