LINQ - 查询以组合3个数据集 - 改进

时间:2018-02-16 21:17:21

标签: c# .net linq

以下代码将根据重要性顺序将3个单独的表组合成一个表。我希望改进这一点 - 也许通过使用查询语法来避免中间阶段。是否有不同的(更好的?)方法来实现相同的结果?

var upsert = new List<KeyValuePair<string, string>>() {
    new KeyValuePair<string, string>("f1","f1-upsert"),
    new KeyValuePair<string, string>("f6","f6-upsert")
};
var fields = new List<KeyValuePair<string, string>>() {
    new KeyValuePair<string, string>("f3","f3-fields"),
    new KeyValuePair<string, string>("f4","f4-fields"),
    new KeyValuePair<string, string>("f6","f6-fields")
};
var server = new List<KeyValuePair<string, string>>() {
    new KeyValuePair<string, string>("f1","f1-server"),
    new KeyValuePair<string, string>("f2","f2-server"),
    new KeyValuePair<string, string>("f5","f5-server")
};

// Order of importance: Upsert > Fields > Server !

var stage = upsert.Concat(fields.Where(f=> !upsert.Any(u=>u.Key==f.Key)));
var final = stage.Concat(server.Where(s=> !stage.Any(j=>j.Key==s.Key))).OrderBy(o=>o.Key);

final.Dump();

LINQPad输出:

Key | Value
------------
f1  | f1-upsert 
f2  | f2-server 
f3  | f3-fields 
f4  | f4-fields 
f5  | f5-server 
f6  | f6-upsert 

2 个答案:

答案 0 :(得分:5)

这可能是也可能不是你想要的,但我个人觉得LINQ很难阅读。

这是一种方法,可以根据您的喜好在多个集合上复制您的逻辑:

public List<KeyValuePair<string, string>> CombineWithPriority(params List<KeyValuePair<string, string>>[] allLists)
 {
     var results = new Dictionary<string, string>();

     foreach (var list in allLists)
     {
         foreach (var kvp in list)
         {
             if (!results.ContainsKey(kvp.Key))
             {
                 results.Add(kvp.Key, kvp.Value);
             }
         }
     }

     return results
         .OrderBy(kvp => kvp.Key)
         .ToList();
 }

致电:CombineWithPriority(upsert, fields, server)。您也可以添加更多级别,所有级别都具有降序优先级。

此方法与您之间的最大区别(除了可读性之外),此方法不会分配临时列表。

答案 1 :(得分:4)

您可以使用GroupBy并仅选择第一个值:

upsert.Concat(fields).Concat(server)
    .GroupBy(x => x.Key, (k, g) => g.First())
    .OrderBy(x => x.Key)
    .Dump();