লিনিকিউ: একটি অবজেক্ট নির্বাচন করুন এবং কোনও নতুন অবজেক্ট তৈরি না করেই কিছু বৈশিষ্ট্য পরিবর্তন করুন


217

আমি একটি নতুন অবজেক্ট তৈরি না করে এবং প্রতিটি সম্পত্তি ম্যানুয়ালি সেট না করেই লিনকুইয়ের ক্যোয়ারী ফলাফল অবজেক্টের কয়েকটি বৈশিষ্ট্য পরিবর্তন করতে চাই। এটা কি সম্ভব?

উদাহরণ:

var list = from something in someList
           select x // but change one property

7
আমি নীচে জারেডারের উত্তরের উপর ভিত্তি করে একটি এক্সটেনশন পদ্ধতি লিখেছিলাম যা আপনাকে আমার উদাহরণের মতো ডিক্যারেটিভ সিনট্যাক্স ব্যবহার করে এটি সম্পাদন করতে দেয়। এটি দেখুন: blog.robvolk.com/2009/05/…
রব ভলক

3
@ রবভোক, লিঙ্কটি মারা গেছে - একটি নতুন পেয়েছে? এখানে একটি সংরক্ষণাগার রয়েছে - লিনকিউ: একটি বিষয় নির্বাচন করুন, তবে একটি নতুন অবজেক্ট তৈরি না করে কিছু বৈশিষ্ট্য পরিবর্তন করুন
কাইলমিট

blog.robvolk.com/2009/05/… ডিএনএস ত্রুটি
কিকিনেট

1
এর জন্যে দুঃখিত! এখানে সঠিক ঠিকানাটি রয়েছে: robvolk.com/…
রব ভলক

1
আরও দেখুন: stackoverflow.com/questions/47836019/...
Revious

উত্তর:


379

ক্যোরিয়াম সিনট্যাক্স কী তা আমি নিশ্চিত নই। তবে এখানে সম্প্রসারিত লিনকিউ এক্সপ্রেশন উদাহরণ রয়েছে।

var query = someList.Select(x => { x.SomeProp = "foo"; return x; })

এটি যা করে তা হ'ল একটি বেনামে পদ্ধতি বনাম এবং প্রকাশের ব্যবহার। এটি আপনাকে একটি ল্যাম্বডায় বেশ কয়েকটি বিবৃতি ব্যবহার করতে দেয়। সুতরাং আপনি সম্পত্তি নির্ধারণ এবং বস্তুকে এই কিছুটা সংযুক্ত পদ্ধতিতে ফেরত দেওয়ার দুটি ক্রিয়াকলাপ একত্রিত করতে পারেন।


4
@ রব, সহজে নয়। কাজটি করার সিনট্যাক্সটি হ'ল ... সবচেয়ে ভাল অপঠনযোগ্য। var কোয়েরি = তালিকা থেকে এটি থেকে ((Func <Foo>) (())>>। it.x = 42; এটি ফেরত দিন;})) ();
জারেডপাড়

35
আমি "একটি বিবৃতি বডি সহ একটি ল্যাম্বডা এক্সপ্রেশন পেয়ে যাচ্ছি একটি এক্সপ্রেশন ট্রিতে রূপান্তর করা যায় না" ত্রুটি। এটি লিনকিউ থেকে এসকিউএল, কোনও পরামর্শের জন্য নয়?
সূর্য

2
আপনার জন্য @ স্পাইডারদেভিল +1 - আপনি কেবল বৈষম্যকে ঘৃণা করেন না? আমি প্রথমবারের মতো এমন পরিস্থিতি দেখিনি যেখানে কোড কেবল লিনক থেকে অবজেক্টের জন্য কাজ করে লিনক থেকে এসকিউএল / ইএফ নয়। এটি এখানে একটি সমাধান হতে পারে , তবে আমার কাছে সময় নেই বলে আমি এখনও এটি ব্যবহারের চেষ্টা করিনি।
ডিসলেক্সিকানবাবোকো

11
লিঙ্ক টু এসকিউএল দিয়ে চেষ্টা করার সময় @ সূর্য এটি বার্তাটি পেয়েছিলাম। এর ToList()আগে একটি যোগ করা কৌশলটি মনে হয়। আপনি কেন এটি পেয়েছেন তা নিশ্চিত নন। যদি এটি সত্তা ফ্রেমওয়ার্ক হয় তবে এটির সাথে এটিও কাজ করে না।
রাজিয়েল 20'15

5
@ সূর্য্য যখন আপনি টোললিস্টকে কল করবেন () আপনি আসলে ডেটাটিকে মেমোরিতে ফিরিয়ে আনছেন। সুতরাং এটি আর এসকিউএল থেকে আসলে লিঙ্ক নয়।
ওক

60

আপনি যদি কেবলমাত্র সমস্ত উপাদানগুলিতে সম্পত্তি আপডেট করতে চান

someList.All(x => { x.SomeProp = "foo"; return true; })

3
ইএফ (সত্তা ফ্রেমওয়ার্ক) এ: কোনও আইইনুমেবলের সমস্ত বস্তুর উপর কোনও সম্পত্তি প্রতিস্থাপন করতে, স্বীকৃত উত্তরটি আমার পক্ষে কাজ করেছে। আমার জন্য কার্যকরী কোড: var myList = _db.MyObjects.Where (o => o.MyProp == "বার") Asঅনুনযোগ্য ()। (X => {x.SomeProp = "foo"; রিটার্ন এক্স;}) নির্বাচন করুন ;
ফায়ারপল

32

আমি এই এক পছন্দ। এটি অন্যান্য লিনাক কমান্ডের সাথে একত্রিত হতে পারে।

from item in list
let xyz = item.PropertyToChange = calcValue()
select item

24

আপনাকে এটি করা থেকে দূরে রাখতে কোনও লিনকিউ ম্যাজিক থাকা উচিত নয়। প্রজেকশনটি ব্যবহার করবেন না যদিও এটি কোনও বেনামি প্রকার ফিরে আসবে।

User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"

এটি আসল বস্তুটি যেমন পরিবর্তন করবে তেমনি:

foreach (User u in UserCollection.Where(u => u.Id > 10)
{
    u.Property = SomeValue;
}

আমি এটি পছন্দ করি, আমার প্রশ্নটি প্রথম উদাহরণে যদি কিছু u> 10 তালিকায় না পাওয়া যায় তবে কী হবে? আমি একটি নাল চেক যুক্ত করেছি এবং মনে হচ্ছে এটি কাজ করে। এছাড়াও LHS আমি আপনার নাম v। +1 রেখেছি। খুব সংক্ষিপ্ত
দেশাইভভ

11

স্ট্যান্ডার্ড ক্যোয়ারী অপারেটরগুলির সাথে এটি সম্ভব নয় - এটি ভাষা ইন্টিগ্রেটেড ক্যোয়ারী, ভাষা ইন্টিগ্রেটেড আপডেট নয়। তবে আপনি এক্সটেনশন পদ্ধতিতে আপনার আপডেটটি আড়াল করতে পারেন।

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);

1
এমন নয় যে আপনি বেস সংগ্রহটি আপডেট করতে চান। আমরা ফলাফল সংগ্রহের সম্পত্তি আপডেট করতে চাই।
মাইকেল ব্রেন্ট

4
ওয়েল LINQ এসকিউএল যা স্ট্রাকচার্ড ঘোরা প্রতিস্থাপন ক্যোয়ারী ল্যাঙ্গুয়েজ, কিন্তু এটি এখনও ক্ষমতা ক্ষমতা প্রকাশ UPDATE, DELETEএবং INSERT। সুতরাং আমি তর্ক করব না যে শব্দার্থক জিনিসটি এই ফাংশনটি প্রতিরোধ করে।
কাইলমিট

5

আপনি যদি একটি Whereধারা দিয়ে আইটেমগুলি আপডেট করতে চান তবে একটি .WW ব্যবহার করে (...) আপনি যদি এটি করেন তবে আপনার ফলাফলগুলি কেটে যাবে:

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();

আপনি কোনও পরিবর্তন না করলেও সর্বদা আইটেমটি ফিরিয়ে দিন। এভাবে এটিকে তালিকায় রাখা হবে।


1

আমরা প্রায়শই এটিতে ছুটে যাই যেখানে আমরা কোনও নতুন অবজেক্ট তৈরি না করে সূচকের মান এবং প্রথম এবং শেষ সূচককে তালিকায় অন্তর্ভুক্ত করতে চাই। এটি আপনাকে বিদ্যমান ক্লাসটি সংশোধন না করে এবং তালিকার প্রথম আইটেমে রয়েছেন কিনা তা জেনেও আপনার তালিকায় আইটেমের অবস্থান, গণনা ইত্যাদি জানতে পারবেন।

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 {}

0

যেহেতু আমি এখানে উত্তরটি সন্ধান করতে পারি নি যা আমি সবচেয়ে ভাল সমাধান হিসাবে বিবেচনা করি, এখানে আমার উপায়:

ডেটা পরিবর্তন করতে "নির্বাচন করুন" ব্যবহার করা সম্ভব তবে কেবল একটি কৌশল দ্বারা। যাইহোক, "নির্বাচন করুন" এর জন্য তৈরি হয় না। এটি "টোলিস্ট" ব্যবহার করার সাথে সাথে কেবলমাত্র সম্পাদনটি সম্পাদন করে, কারণ লিনক ডেটা প্রয়োজন হওয়ার আগেই সম্পাদন করে না। যাইহোক, সর্বোত্তম সমাধানটি "ফোরচ" ব্যবহার করা। নিম্নলিখিত কোডে, আপনি দেখতে পারেন:

    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);
            ;
            }
        }
    }

"ফোরচ" করার আগে আপনি একটি লিনাক নির্বাচনও করতে পারেন ...


0
var item = (from something in someList
       select x).firstordefault();

পাবেন itemএবং তারপরে আপনি item.prop1=5;নির্দিষ্ট সম্পত্তি পরিবর্তন করতে পারেন ।

অথবা আপনি ডিবি থেকে আইটেমের একটি তালিকা পেতে চান prop1এবং এটি প্রত্যাবর্তিত তালিকার প্রতিটি আইটেমের সম্পত্তি একটি নির্দিষ্ট মানতে পরিবর্তন করতে চান ? যদি তাই হয় তবে আপনি এটি করতে পারতেন (আমি এটি ভিবিতে করছি কারণ আমি এটি আরও ভাল জানি):

dim list = from something in someList select x
for each item in list
    item.prop1=5
next

( listআপনার পরিবর্তনগুলি দিয়ে ফিরে আসা সমস্ত আইটেম থাকবে)


এটি কাজ করবে এমন সময়, আমি মনে করি যে ওপি for eachলুপ না লিখে কীভাবে লিনকিউ বিবৃতি লিখতে বলছে ।
ফুজিফেস


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.