मैं एक नई वस्तु बनाने और हर संपत्ति को मैन्युअल रूप से सेट किए बिना 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()
इससे पहले कि जोड़ने के लिए लगता है चाल। सुनिश्चित नहीं हैं कि आपको ऐसा क्यों मिलता है। यदि यह एंटिटी फ्रेमवर्क है, तो यह उसके साथ भी काम नहीं करता है।
यदि आप अभी सभी तत्वों पर संपत्ति को अद्यतन करना चाहते हैं
someList.All(x => { x.SomeProp = "foo"; return true; })
मुझे यह पसंद है। इसे अन्य लाइनक कमांड के साथ जोड़ा जा सकता है।
from item in list
let xyz = item.PropertyToChange = calcValue()
select item
ऐसा करने से आपको कोई 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
खंड के साथ आइटम अद्यतन करना चाहते हैं , तो (यदि ...) आपके परिणामों को कम कर देगा यदि आप ऐसा करते हैं:
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 {}
चूँकि मुझे इसका उत्तर नहीं मिला, जिसे मैं सबसे अच्छा समाधान मानता हूँ, यहाँ मेरा तरीका है:
डेटा को संशोधित करने के लिए "चयन करें" का उपयोग करना संभव है, लेकिन सिर्फ एक चाल के साथ। वैसे भी, "सेलेक्ट" उसके लिए नहीं बना है। यह केवल "ToList" के साथ उपयोग किए जाने पर संशोधन को निष्पादित करता है, क्योंकि डेटा की आवश्यकता होने से पहले Linq का निष्पादन नहीं होता है। वैसे भी, सबसे अच्छा समाधान "फोरच" का उपयोग कर रहा है। निम्नलिखित कोड में, आप देख सकते हैं:
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
User u = UserCollection.Single(u => u.Id == 1);
u.FirstName = "Bob"