我正在使用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有很多字段。
由于
答案 0 :(得分:1)
虽然LINQ不允许您修改项目,但您可以使用以下几种方法:
OneHash
和TwoHash
是基于item
的其他属性计算的,因此您可以将已存储的属性替换为已计算的属性phraseSources
内的项目(如果您打算保存它们,则需要执行此操作),您可以创建具有计算属性集的副本OneHash
和TwoHash
未存储在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
是完成这项工作的完美工具。