LINQ:
যখনই আমি জানতে পারি যে কোয়েরিটি একটি একক রেকর্ডটি ফেরত দেবে তখন Single()
অপারেটরটি ব্যবহার করা কি আরও দক্ষ ?First()
পার্থক্য আছে কি?
LINQ:
যখনই আমি জানতে পারি যে কোয়েরিটি একটি একক রেকর্ডটি ফেরত দেবে তখন Single()
অপারেটরটি ব্যবহার করা কি আরও দক্ষ ?First()
পার্থক্য আছে কি?
উত্তর:
আমি জানি অন্যদের লিখেছি কেন তুমি এক বা অন্যান্য ব্যবহার করেন, কিন্তু আমি চিত্রিত চাই তুমি কেন এক, যখন আপনি ব্যবহার করা উচিত নয় মানে অন্যান্য।
দ্রষ্টব্য: আমার কোডে, আমি সাধারণত ব্যবহার করব FirstOrDefault()
এবং SingleOrDefault()
এটি একটি ভিন্ন প্রশ্ন।
উদাহরণস্বরূপ, একটি টেবিল নিন যা Customers
একটি সমন্বিত কী ( ID
, Lang
) ব্যবহার করে বিভিন্ন ভাষায় সঞ্চয় করে :
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).First();
উপরের এই কোডটি একটি সম্ভাব্য যুক্তি ত্রুটির পরিচয় করিয়েছে (এটি সনাক্ত করা কঠিন)। এটি একাধিক রেকর্ড ফেরত আসবে (ধরে নিলে একাধিক ভাষায় আপনার গ্রাহক রেকর্ড রয়েছে) তবে এটি সর্বদা প্রথমটি ফিরে আসবে ... যা কখনও কখনও কার্যকর হতে পারে ... তবে অন্যরা নয়। এটি অনির্দেশ্য।
যেহেতু আপনার উদ্দেশ্যটি একটি একক Customer
ব্যবহার ফেরত দেবে Single()
;
নিম্নলিখিতগুলি একটি ব্যতিক্রম ছুঁড়ে ফেলবে (যা এই ক্ষেত্রে আপনি যা চান):
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single();
তারপরে, আপনি কেবল নিজেকে কপালে আঘাত করুন এবং নিজেকে বলুন ... ওফস! ভুলে গেছি ভাষার ক্ষেত্র! নিম্নলিখিতটি সঠিক সংস্করণ:
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == "en" ).Single();
First()
নিম্নলিখিত পরিস্থিতিতে দরকারী:
DBContext db = new DBContext();
NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First();
এটি এক অবজেক্টকে ফিরিয়ে দেবে, এবং যেহেতু আপনি বাছাই ব্যবহার করছেন, এটি ফিরে আসা সবচেয়ে সাম্প্রতিক রেকর্ড।
ব্যবহার Single()
যখন আপনি এটি স্পষ্টভাবে সবসময় 1 রেকর্ড ফেরত পাঠাবেন মনে যুক্তিবিজ্ঞান ত্রুটিগুলি এড়ানোর সাহায্য করবে।
customers.Where(predicate).Single()
customers.Single(predicate)
কি পার্থক্য আছে ?
যদি মানদণ্ডের সাথে একাধিক রেকর্ড মেলে তবে একক ব্যতিক্রম ছুঁড়ে ফেলবে। প্রথমে সর্বদা তালিকা থেকে প্রথম রেকর্ড নির্বাচন করবে। যদি ক্যোয়ারী মাত্র 1 টি রেকর্ড করে, আপনি যেতে পারেন First()
।
InvalidOperationException
সংগ্রহটি ফাঁকা থাকলে উভয়ই একটি ব্যতিক্রম ছুঁড়ে মারবে । বিকল্পভাবে আপনি ব্যবহার করতে পারেন SingleOrDefault()
। তালিকাটি খালি থাকলে এটি ব্যতিক্রম করবে না
একক ()
একটি প্রশ্নের একক নির্দিষ্ট উপাদান প্রদান করে Return
যখন ব্যবহার : ঠিক 1 উপাদান আশা করা হয়; 0 বা 1 এর বেশি নয়। তালিকাটি খালি থাকলে বা একাধিক উপাদান থাকলে এটি একটি ব্যতিক্রম ছুঁড়ে দেবে "সিকোয়েন্সে একাধিক উপাদান রয়েছে"
SingleOrDefault ()
কোনও প্রশ্নের কোনও একক নির্দিষ্ট উপাদান বা কোনও ফলাফল না পাওয়া গেলে একটি ডিফল্ট মান প্রদান করে
কখন ব্যবহার করুন : যখন 0 বা 1 উপাদান প্রত্যাশিত হয়। তালিকায় 2 বা ততোধিক আইটেম থাকলে এটি একটি ব্যতিক্রম ছুঁড়ে দেবে।
প্রথম ()
একাধিক ফলাফলের সাথে ক্যোয়ারির প্রথম উপাদানটি ফেরত দেয়।
যখন ব্যবহার করুন : যখন 1 বা ততোধিক উপাদান প্রত্যাশিত হয় এবং আপনি কেবল প্রথমটি চান। তালিকায় কোনও উপাদান না থাকলে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলবে।
FirstOrDefault ()
উপাদানের পরিমাণের সাথে তালিকার প্রথম উপাদান বা তালিকা খালি থাকলে একটি ডিফল্ট মান প্রদান করে।
যখন ব্যবহার করুন : যখন একাধিক উপাদান প্রত্যাশিত হয় এবং আপনি কেবল প্রথমটি চান। অথবা তালিকাটি খালি এবং আপনি নির্দিষ্ট ধরণের জন্য একটি ডিফল্ট মান চান
default(MyObjectType)
। উদাহরণস্বরূপ: তালিকার ধরণটি তালিকাlist<int>
থেকে প্রথম সংখ্যাটি বা তালিকাটি শূন্য থাকলে 0 প্রদান করবে। যদি তা হয় তবে এটিlist<string>
তালিকা থেকে প্রথম স্ট্রিংটি ফেরত দেবে বা তালিকাটি ফাঁকা থাকলে নালার।
First
হলে কেবল "1 টিরও বেশি" নয়, এবং কোনও পরিমাণের উপাদান সহ ব্যবহার করতে পারেন । FirstOrDefault
এই দুটি পদ্ধতির মধ্যে একটি সূক্ষ্ম, অর্থপূর্ণ পার্থক্য রয়েছে।
Single
একটি ক্রম থেকে প্রথম (এবং কেবল) উপাদানটি পুনরুদ্ধার করতে ব্যবহার করুন যাতে একটি উপাদান থাকা উচিত এবং আরও কিছু না। যদি ক্রমটি উপাদানটির চেয়ে বেশি থাকে তবে আপনার অনুরোধটি Single
একটি ব্যতিক্রম ছুঁড়ে ফেলবে কারণ আপনি ইঙ্গিত করেছেন যে কেবলমাত্র একটি উপাদান থাকা উচিত।
First
একটি ক্রম থেকে প্রথম উপাদানটি পুনরুদ্ধার করতে ব্যবহার করুন যাতে কোনও সংখ্যক উপাদান থাকতে পারে। যদি ক্রমটি উপাদানটির চেয়ে বেশি থাকে তবে আপনার অনুরোধটি First
কোনও ব্যতিক্রম ছুঁড়ে ফেলবে না কারণ আপনি নির্দেশ করেছেন যে অনুক্রমের জন্য আপনাকে কেবল প্রথম উপাদানটির প্রয়োজন এবং আরও উপস্থিত থাকলে যত্ন নেই care
যদি ক্রমটি কোনও উপাদান না থাকে তবে উভয় পদ্ধতি কলই ব্যতিক্রম ছুঁড়ে ফেলবে কারণ উভয় পদ্ধতিই কমপক্ষে একটি উপাদান উপস্থিত থাকার প্রত্যাশা করে।
আপনি যদি বিশেষত একাধিক আইটেমের ইভেন্টে ফেলে দেওয়া ব্যতিক্রম চান না, তবে ব্যবহার করুনFirst()
।
উভয়ই দক্ষ, প্রথম আইটেমটি নিন। First()
কিছুটা বেশি দক্ষ কারণ এটি দ্বিতীয় আইটেম আছে কিনা তা পরীক্ষা করে দেখার বিরক্ত করে না।
পার্থক্যটি হ'ল Single()
প্রত্যাশা করা হয় যে গণনাটিতে একটি মাত্র আইটেম শুরু হবে এবং এটি যদি একের বেশি থাকে তবে একটি ব্যতিক্রম ছুঁড়ে দেবে। আপনি যদি বিশেষত এই ক্ষেত্রে কোনও ব্যতিক্রম চান তবে আপনি ব্যবহার করুন ।.Single()
যদি আমি স্মরণ করি, তবে সিঙ্গেল () প্রথমটির পরে আর কোনও উপাদান রয়েছে কিনা তা পরীক্ষা করে (এবং যদি এটি হয় তবে একটি ব্যতিক্রম ছুঁড়ে দেয়), যখন ফার্স্ট () এটি পাওয়ার পরে থামে। ক্রমটি খালি থাকলে উভয়ই একটি ব্যতিক্রম ছুঁড়ে।
ব্যক্তিগতভাবে, আমি সর্বদা প্রথম () ব্যবহার করি।
পারফরম্যান্স সম্পর্কিত: একজন সহকর্মী এবং আমি সিঙ্গেল বনাম ফার্স্ট (বা সিঙ্গেলঅরডিফল্ট বনাম ফার্স্টআরডিফল্ট) এর অভিনয় নিয়ে আলোচনা করছিলাম, এবং আমি এই পয়েন্টটি নিয়ে তর্ক করছিলাম যে ফার্স্ট (বা ফার্স্টআরডিফল্ট) দ্রুত হবে এবং পারফরম্যান্স উন্নত করবে (আমি সবই আমাদের অ্যাপ তৈরির বিষয়ে আছি দ্রুত রান).
স্ট্যাক ওভারফ্লোতে আমি বেশ কয়েকটি পোস্ট পড়েছি যা এই বিতর্ক। কেউ কেউ বলেন যে সিঙ্গেলের পরিবর্তে ফার্স্ট ব্যবহার করে ছোট পারফরম্যান্স লাভ রয়েছে। এটি কারণ প্রথমটি কেবল প্রথম আইটেমটি ফিরিয়ে আনবে যখন নকল নেই তা নিশ্চিত করার জন্য সিঙ্গেলকে অবশ্যই সমস্ত ফলাফল স্ক্যান করতে হবে (যেমন: এটি যদি টেবিলের প্রথম সারিতে আইটেমটি খুঁজে পায় তবে এটি অন্য প্রতিটি সারি স্ক্যান করে শর্তটির সাথে মেলে এমন কোনও দ্বিতীয় মান নেই যা নিশ্চিত করে তা ত্রুটি ছুঁড়ে দেবে)) আমার মনে হয়েছিল আমি দৃ solid় ভূমিতে ছিলাম "প্রথম" "সিঙ্গেল" এর চেয়ে দ্রুততর তাই আমি এটি প্রমাণ করতে এবং বিতর্কটিকে বিশ্রামে রাখার উদ্দেশ্যে রওনা হয়েছি।
আমি আমার ডাটাবেসে একটি পরীক্ষা সেটআপ করেছি এবং আইডি ইউনিকআইডেন্টিফায়ার বিদেশী ইউনিক আইডেন্টিফায়ার ইনফরমেশন (50) এর 1000,000 সারি যুক্ত করেছি ("0" সংখ্যার স্ট্রিং দিয়ে "999,9999" দিয়ে পূর্ণ
আমি ডেটা লোড করেছি এবং প্রাথমিক কী ক্ষেত্র হিসাবে আইডি সেট করেছি।
লিনকপ্যাড ব্যবহার করে, আমার লক্ষ্যটি দেখানো ছিল যে আপনি যদি সিঙ্গেল ব্যবহার করে 'বিদেশী' বা 'তথ্য' তে কোনও মান অনুসন্ধান করেন, তবে এটি ফার্স্ট ব্যবহারের চেয়ে আরও খারাপ be
আমি যে ফলাফল পেয়েছি তা ব্যাখ্যা করতে পারি না। প্রায় প্রতিটি ক্ষেত্রেই সিঙ্গল বা সিঙ্গেলঅরডিফল্ট ব্যবহার করা কিছুটা দ্রুত ছিল। এটি আমার কাছে কোনও যৌক্তিক ধারণা তৈরি করে না, তবে আমি তা ভাগ করে নিতে চেয়েছিলাম।
প্রাক্তন: আমি নিম্নলিখিত প্রশ্নগুলি ব্যবহার করেছি:
var q = TestTables.First(x=>x.Info == "314638") ;
//Vs.
Var q = TestTables.Single(x=>x.Info =="314638") ; //(this was slightly faster to my surprise)
আমি 'বিদেশী' কী ক্ষেত্রের অনুরূপ প্রশ্নের চেষ্টা করেছি যা ভেবে দেখানো হয়নি যে প্রথমটি আরও দ্রুত প্রমাণিত হবে, তবে সিঙ্গেল আমার পরীক্ষাগুলিতে সর্বদা কিছুটা দ্রুত ছিল।
তারা ভিন্ন ধরনের. দু'জনেই জোর দিয়েছিলেন যে ফলাফলের সেটটি খালি নয়, তবে একক এটিও দাবি করে যে 1 টির বেশি ফলাফল নেই। আমি ব্যক্তিগতভাবে সিঙ্গেলগুলি এমন ক্ষেত্রে ব্যবহার করি যেখানে আমি কেবলমাত্র 1 টি ফলাফলের প্রত্যাশা করি কারণ 1 টির বেশি ফলাফল ফিরে পাওয়া একটি ত্রুটি এবং সম্ভবত এরূপ হিসাবে দেখা উচিত।
পার্থক্য পেতে আপনি সাধারণ উদাহরণ চেষ্টা করতে পারেন। ব্যতিক্রম 3 লাইনে ফেলে দেওয়া হবে;
List<int> records = new List<int>{1,1,3,4,5,6};
var record = records.First(x => x == 1);
record = records.Single(x => x == 1);
কর্মচারী সত্তা রেকর্ডস:
Employeeid = 1
: এই আইডি সহ কেবলমাত্র একজন কর্মচারী
Firstname = Robert
: এই নামের একাধিক কর্মচারী
Employeeid = 10
: এই আইডি সহ কোনও কর্মচারী নেই
এখন এটা কি বুঝতে প্রয়োজন Single()
এবং First()
বিস্তারিতভাবে মানে।
একক ()
একক () একক রেকর্ডটি ফেরত দিতে ব্যবহৃত হয় যা এক টেবিলের মধ্যে স্বতন্ত্রভাবে উপস্থিত থাকে, সুতরাং নীচের কোয়েরিটি সেই কর্মচারীকে ফিরিয়ে দেবে যার employeed =1
কারণ আমাদের কেবলমাত্র একজন কর্মচারী যার Employeed
1। যদি আমাদের কাছে দুটি রেকর্ড থাকে EmployeeId = 1
তবে এটি ত্রুটি ছুঁড়ে ফেলে (দেখুন দেখুন) দ্বিতীয় কোয়েরিতে নীচে ত্রুটি যেখানে আমরা একটি উদাহরণ ব্যবহার করছি Firstname
।
Employee.Single(e => e.Employeeid == 1)
উপরেরটি একটি একক রেকর্ড ফিরিয়ে দেবে, যার আছে employeeId
Employee.Single(e => e.Firstname == "Robert")
উপরেরগুলি একটি ব্যতিক্রম ছুঁড়ে ফেলবে কারণ একাধিক রেকর্ডগুলি টেবিলে রয়েছে FirstName='Robert'
। ব্যতিক্রম হবে
অবৈধ অপারেশন এক্সেক্সশন: সিকোয়েন্সে একাধিক উপাদান রয়েছে
Employee.Single(e => e.Employeeid == 10)
এটি আবারও একটি ব্যতিক্রম ছুঁড়ে ফেলবে কারণ আইডি = 10 এর জন্য কোনও রেকর্ড বিদ্যমান নেই। ব্যতিক্রম হবে
অবৈধ অপারেশন এক্সসেপশন: সিকোয়েন্সে কোনও উপাদান নেই।
জন্য EmployeeId = 10
এটা নাল ফিরে আসবে, কিন্তু আমরা ব্যবহার করছেন Single()
এটি একটি ত্রুটির নিক্ষেপ করা হবে। নাল ত্রুটি পরিচালনা করার জন্য আমাদের ব্যবহার করা উচিত SingleOrDefault()
।
প্রথম ()
প্রথম () একাধিক রেকর্ড থেকে সংশ্লিষ্ট রেকর্ডগুলি অনুসারে আরোহী ক্রমে সাজানো থাকে birthdate
তাই এটি পুরানো 'রবার্ট' ফিরিয়ে দেবে।
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Firstname == "Robert")
উপরে ডিওবি অনুসারে রবার্টকে পুরানো ফিরিয়ে দেওয়া উচিত।
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Employeeid == 10)
উপরে id = 10 এর কোনও রেকর্ড বিদ্যমান না থাকায় একটি ব্যতিক্রম ছুঁড়ে ফেলবে। একটি নাল ব্যতিক্রম এড়াতে আমাদের FirstOrDefault()
পরিবর্তে ব্যবহার করা উচিত First()
।
দ্রষ্টব্য: আমরা কেবল তখনই ব্যবহার করতে পারি First()
/ Single()
যখন আমরা একেবারে নিশ্চিত হয়ে থাকি যে এটি কোনও নাল মান দিতে পারে না।
উভয় ফাংশনে সিঙ্গেলঅরডিফল্ট () বা ফার্স্টওরডিফল্ট () ব্যবহার করুন যা কোনও নাল ব্যতিক্রম পরিচালনা করবে, কোনও রেকর্ড না পাওয়া গেলে এটি বাতিল হয়ে যাবে।