是否可以使用LINQ表达式修改字段而不使用SELECT?

时间:2017-12-04 15:03:35

标签: c# linq

我正在使用LINQ来填充PhraseSource列表。在此之后我使用foreach来修改列表:

List<PhraseSource> phraseSources = App.DB.db1.Table<PhraseSource>().ToList();

List<PhraseSource> phraseSources2 = phraseSources
    .Where(p => categorySources.Any(c => c.Id == p.CategoryId)).ToList();

foreach (var item in phraseSources2)
{
    item.OneHash = Math.Abs(item.Id.GetHashCode() % 10);
    item.TwoHash = Math.Abs(item.Id.GetHashCode() % 100);
}

我对LINQ的了解非常有限,这是给我的代码。

有没有办法可以将foreach组合到LINQ表达式中,或者我必须以这种方式使用foreach来修改数据。请注意,我认为我可以使用SELECT,但我想知道是否有另一种方式,因为PhraseSource有很多字段。

由于

2 个答案:

答案 0 :(得分:1)

虽然LINQ不允许您修改项目,但您可以使用以下几种方法:

  • 由于OneHashTwoHash是基于item的其他属性计算的,因此您可以将已存储的属性替换为已计算的属性
  • 如果您不需要修改phraseSources内的项目(如果您打算保存它们,则需要执行此操作),您可以创建具有计算属性集的副本
  • 如果OneHashTwoHash未存储在PhraseSource表中,您可以将其从PhraseSource对象中删除,并将其添加为匿名&#34的属性;包装&#34;宾语。这将允许您在LINQ查询中计算属性。

第一种方法如下:

public class PhraseSource {
    ...
    public int OneHash => Id.GetHashCode() % 10;
    public int TwoHash => Id.GetHashCode() % 100;
    ...
}

注意:在不支持lambda-bodied属性的旧C#版本中,使用getter语法:

public class PhraseSource {
    ...
    public int OneHash { get { return Id.GetHashCode() % 10; } }
    public int TwoHash { get { return Id.GetHashCode() % 100; } }
    ...
}

答案 1 :(得分:1)

LIN Q 是查询数据源,而不是修改它。强烈建议不要滥用LINQ来修改它。在这种情况下,您有一个列表,因此您可以使用List.ForEach

phraseSources2.ForEach(item => {
    item.OneHash = Math.Abs(item.Id.GetHashCode() % 10);
    item.TwoHash = Math.Abs(item.Id.GetHashCode() % 100);
});

虽然我没有看到foreach的好处。

对于它的价值,您可以编写一个扩展名,允许使用任何序列:

public static void ForEachDo<T>(this IEnumerable<T> seq, Action<T> doWithEveryItem, Action doIfEmpty = null)
{
    bool isEmpty = true;
    foreach (T item in seq)
    {
        isEmpty = false;
        doWithEveryItem(item);
    }
    if (isEmpty && doIfEmpty != null)
        doIfEmpty();
}

现在你可以使用它,即使它不是一个列表:

var phraseSources2 = phraseSources.Where(p => categorySources.Any(c => c.Id == p.CategoryId));
phraseSources2.ForEachDo(item=> {
    item.OneHash = Math.Abs(item.Id.GetHashCode() % 10);
    item.TwoHash = Math.Abs(item.Id.GetHashCode() % 100);
})

但同样,foreach是完成这项工作的完美工具。