새 개체를 만들고 모든 속성을 수동으로 설정하지 않고 LINQ 쿼리 결과 개체의 일부 속성을 변경하고 싶습니다. 이게 가능해?
예:
var list = from something in someList
select x // but change one property
새 개체를 만들고 모든 속성을 수동으로 설정하지 않고 LINQ 쿼리 결과 개체의 일부 속성을 변경하고 싶습니다. 이게 가능해?
예:
var list = from something in someList
select x // but change one property
답변:
쿼리 구문이 무엇인지 잘 모르겠습니다. 그러나 다음은 확장 된 LINQ 표현 예제입니다.
var query = someList.Select(x => { x.SomeProp = "foo"; return x; })
이것이하는 것은 익명의 방법과 표현을 사용하는 것입니다. 이를 통해 하나의 람다에서 여러 명령문을 사용할 수 있습니다. 따라서 속성을 설정하고 객체를이 간결한 방법으로 반환하는 두 가지 작업을 결합 할 수 있습니다.
ToList()
전에 트릭을 추가하는 것 같습니다. 왜 그런지 모르겠습니다. Entity Framework 인 경우에도 작동하지 않습니다.
모든 요소의 속성을 업데이트하려는 경우
someList.All(x => { x.SomeProp = "foo"; return true; })
LINQ 마법이 없어야합니다. 익명 유형을 반환하지만 투영을 사용하지 마십시오.
User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"
그러면 실제 객체와 다음이 수정됩니다.
foreach (User u in UserCollection.Where(u => u.Id > 10)
{
u.Property = SomeValue;
}
표준 쿼리 연산자로는 불가능합니다. 언어 통합 업데이트가 아니라 언어 통합 쿼리입니다. 그러나 확장 방법으로 업데이트를 숨길 수 있습니다.
public static class UpdateExtension
{
public static IEnumerable<Car> ChangeColorTo(
this IEnumerable<Car> cars, Color color)
{
foreach (Car car in cars)
{
car.Color = color;
yield return car;
}
}
}
이제 다음과 같이 사용할 수 있습니다.
cars.Where(car => car.Color == Color.Blue).ChangeColorTo(Color.Red);
UPDATE
, DELETE
및 INSERT
. 그래서 나는 의미론 이이 기능을 방해하는 것이라고 주장하지 않을 것입니다.
Where
절을 사용하여 항목을 업데이트하려면 .Where (...)를 사용하면 다음 과 같은 경우 결과가 잘립니다.
mylist = mylist.Where(n => n.Id == ID).Select(n => { n.Property = ""; return n; }).ToList();
다음과 같이 목록에서 특정 항목을 업데이트 할 수 있습니다.
mylist = mylist.Select(n => { if (n.Id == ID) { n.Property = ""; } return n; }).ToList();
변경하지 않아도 항상 반품하십시오. 이런 식으로 목록에 유지됩니다.
우리는 종종 새로운 객체를 만들지 않고 색인 값과 목록의 첫 번째 및 마지막 표시기를 포함하려고합니다. 이를 통해 기존 클래스를 수정하지 않고 목록의 첫 번째 항목인지 마지막 항목인지 알 필요없이 목록에서 항목의 위치, 열거 등을 알 수 있습니다.
foreach (Item item in this.Items
.Select((x, i) => {
x.ListIndex = i;
x.IsFirst = i == 0;
x.IsLast = i == this.Items.Count-1;
return x;
}))
다음을 사용하여 클래스를 간단하게 확장 할 수 있습니다.
public abstract class IteratorExtender {
public int ListIndex { get; set; }
public bool IsFirst { get; set; }
public bool IsLast { get; set; }
}
public class Item : IteratorExtender {}
최고의 해결책이라고 생각되는 답변을 찾지 못했습니다.
"선택"을 사용하여 데이터를 수정하는 것이 가능하지만, 단지 트릭이 필요합니다. 어쨌든, "선택"은 그런 것이 아닙니다. Linq는 데이터가 필요하기 전에 실행되지 않기 때문에 "ToList"와 함께 사용될 때 수정을 실행합니다. 어쨌든 가장 좋은 해결책은 "foreach"를 사용하는 것입니다. 다음 코드에서 볼 수 있습니다.
class Person
{
public int Age;
}
class Program
{
private static void Main(string[] args)
{
var persons = new List<Person>(new[] {new Person {Age = 20}, new Person {Age = 22}});
PrintPersons(persons);
//this doesn't work:
persons.Select(p =>
{
p.Age++;
return p;
});
PrintPersons(persons);
//with "ToList" it works
persons.Select(p =>
{
p.Age++;
return p;
}).ToList();
PrintPersons(persons);
//This is the best solution
persons.ForEach(p =>
{
p.Age++;
});
PrintPersons(persons);
Console.ReadLine();
}
private static void PrintPersons(List<Person> persons)
{
Console.WriteLine("================");
foreach (var person in persons)
{
Console.WriteLine("Age: {0}", person.Age);
;
}
}
}
"foreach"전에 linq를 선택할 수도 있습니다 ...
var item = (from something in someList
select x).firstordefault();
를 얻으면 특정 속성을 변경하기 위해 item
할 수 item.prop1=5;
있습니다.
또는 db에서 항목 목록을 가져 와서 prop1
반환 된 목록의 각 항목에 대한 속성 을 지정된 값으로 변경 하시겠습니까? 그렇다면 당신은 이것을 할 수 있습니다 (나는 그것을 더 잘 알고 있기 때문에 VB에서하고 있습니다) :
dim list = from something in someList select x
for each item in list
item.prop1=5
next
( list
변경 사항과 함께 반환 된 모든 항목이 포함됩니다)
for each
루프 를 작성하지 않고 LINQ 문을 작성하는 방법을 묻고 있다고 생각합니다 .
2020 년에이 MoreLinq
Pipe
방법을 사용합니다 . https://morelinq.github.io/2.3/ref/api/html/M_MoreLinq_MoreEnumerable_Pipe__1.htm