从linq获取多个项目

时间:2013-08-19 10:15:19

标签: c# .net performance linq

我的应用程序中有遗留代码,并希望对其进行优化。 arrayOfAttrValue具有唯一属性。我可以使用LINQ来实现循环优化吗?如果是的话那么请你告诉我怎么样?

foreach (AttrValue attr in arrayOfAttrValue)
{
    switch(attr.Attribute)
    {
        case Constants.Gender
            mymodel.Gender = attr.Value;
            break;
        case Constants.Identifier
            mymodel.AppIdentifier = attr.Value;
            break;
    }
}

我的意图不一定只使用LINQ。任何其他最小化循环的方法也会有所帮助。

感谢。

4 个答案:

答案 0 :(得分:1)

不,你不能在“真正的”LINQ中做到这一点,因为LINQ是关于从旧对象生成新对象。此处mymodel是您要修改的预先存在的对象。

您可以使用Array.ForEachList.ForEach,但

  1. 他们不是“真正的”LINQ和

  2. 结果代码是等效的(稍慢一点,因为会有代表)

  3. 然而,downvoter可能想要一些LINQ,所以我会给一些LINQ:

    arrayOfAttrValue.All(attr => {
        mymodel.Gender = attr.Attribute == Constants.Gender ? attr.Value : mymodel.Gender;
        mymodel.AppIdentifier = attr.Attribute == Constants.Identifier ? attr.Value : mymodel.AppIdentifier;
        return true;
    });
    

    少一行,忽略{}行。

答案 1 :(得分:1)

您有属性列表,表示键值对。保持这种数据结构的自然方式是字典。因此,将输入数据格式转换为字典:

var attributes = arrrayOfAttrValue.ToDictionary(a => a.Attribute, a => a.Value);

或者如果每个属性在您的数组中不唯一,则字典创建将更加困难,但这是您拥有的数据格式。为了更轻松地处理您的数据,您应该将它们转换为方便的格式:

var attributes = arrayOfAttrValue
                   .GroupBy(a => a.Attribute)                
                   .ToDictionary(g => g.Key, g => g.Select(a => a.Value).Last());

创建属性字典后,您只需检查属性是否具有值,并将该值分配给模型属性。对于任何读者来说,现在检索的属性都很简单明了:

if (attributes.ContainsKey(Constants.Gender))
    model.Gender = attributes[Constants.Gender];

if (attributes.ContainsKey(Constants.Identifier))
    model.AppIdentifier = attributes[Constants.Identifier];   

答案 2 :(得分:1)

无需在代码中手动执行循环,只需使用.LastOrDefault()

即可
mymodel.Gender = arrayOfAttrValue
    .Where(attr => attr.Attribute == Constants.Gender)
    .Select(attr => attr.Value).LastOrDefault() ?? mymodel.Gender;
mymodel.AppIdentifier = arrayOfAttrValue
    .Where(attr => attr.Attribute == Constants.Identifier)
    .Select(attr => attr.Value).LastOrDefault() ?? mymodel.AppIdentifier;

?? mymodel.Gender确保我们未将其设置为Default(T)(即null),否则将其设置为先前的值。然后,这与您最初问题的功能逻辑相匹配。

这样做可以很清楚你想要做什么。当然,这种方法意味着你将数组循环两次,但是如果你的数组实际上是一个数组,那么这个性能成本将非常小。

如果您仍然遇到性能问题,那么您可能需要考虑使用比arrayOfAttrValue更好的数据结构(Attribute可以访问的内容,例如Dictionary<,>

答案 3 :(得分:-1)

你不需要LINQ因为它会使问题变得更复杂,只是因为循环没问题:

bool gotGender, gotAppIdentifier;
foreach (AttrValue attr in arrayOfAttrValue.Reverse())
{
  switch(attr.Attribute)
  {
   case Constants.Gender:
      if(!gotGender){
        mymodel.Gender = attr.Value
        gotGender = true;
      }
      break;
   case Constants.Identifier:
      if(!gotAppIdentifier){
        mymodel.AppIdentifier = attr.Value 
        gotAppItentifier = true;
      }
      break;
  }
  if(gotGender&&gotAppIdentifier) break;
}