কীভাবে লিনিক্যু সাম ()) 0 ফেরত যেতে বাধ্য করা যায় যখন উত্স সংগ্রহটি খালি থাকে


183

মূলত আমি যখন নিম্নলিখিত কোয়েরিটি করি তখন কোনও লিড মিলে না গেলে নিম্নলিখিত কোয়েরিটি একটি ব্যতিক্রম ছুঁড়ে দেয়। সেক্ষেত্রে আমি ব্যতিক্রম ছোঁড়ার পরিবর্তে যোগফলের সমান 0 করতে পছন্দ করব। এটি কি নিজেই ক্যোয়ারীতে সম্ভব হবে - আমার অর্থ কোয়েরিটি সংরক্ষণ এবং চেক করার চেয়ে query.Any()?

double earnings = db.Leads.Where(l => l.Date.Day == date.Day
                && l.Date.Month == date.Month
                && l.Date.Year == date.Year
                && l.Property.Type == ProtectedPropertyType.Password
                && l.Property.PropertyId == PropertyId).Sum(l => l.Amount);

2
Whereফিরে হবে না nullযদি এটা কোন রেকর্ড খুঁজে পান না, এটা শূন্য আইটেম একটি তালিকা ফিরে আসবে। ব্যতিক্রম কী?
মাইক পেরেনউড

3
ব্যতিক্রম কী?
টোটো

3
আমি ব্যতিক্রমটি পেয়েছি: 'ইন্ট 32' টাইপের মান টাইনে কাস্ট ব্যর্থ হয়েছে কারণ বস্তুগত মানটি শূন্য। হয় ফলাফলের জেনেরিক প্যারামিটার বা ক্যোয়ারিতে অবশ্যই একটি নলাবদ্ধ টাইপ ব্যবহার করা উচিত।
জন মায়ার

1
@ স্টিজন, আপনি যা করেছেন তা এখনও কাজ করবে না। সমস্যাটি যেভাবে SQLউত্পন্ন হয়। Amountআসলে এটি নয় null, এটি শূন্য ফলাফলগুলি কীভাবে পরিচালনা করে তা আশেপাশের সমস্যা a যে উত্তরটি দেওয়া হয়েছিল তা একবার দেখুন।
মাইক পেরেনউড

39
আপনার ডলারের পরিমাণের জন্য দ্বিগুণ ব্যবহার করা উচিত নয় ! এমনকি ভগ্নাংশ ডলার পরিমাণ। কখনই, কখনই ডাবল ব্যবহার করবেন না যখন সঠিক পরিমাণের উদ্দেশ্যে হয়। আপনার ডাটাবেস কলামগুলি হওয়া উচিত decimal, আপনার কোড ব্যবহার করা উচিত decimal। পরিসংখ্যান বা তারার আলোকসজ্জা বা কোনও স্ট্রোস্টিক প্রক্রিয়া বা ইলেকট্রনের চার্জের ফলাফলের জন্য কেউ আপনাকে সেগুলি ব্যবহার করতে না বলা পর্যন্ত আপনার প্রোগ্রামিং ক্যারিয়ারের সম্পর্কে floatএবং doubleআপনার প্রোগ্রামিং কেরিয়ার সম্পর্কে জানতেন ! ততক্ষণ পর্যন্ত, আপনি এটি ভুল করছেন
এরিক

উত্তর:


390

আপনার ক্যোয়ারী এটিতে পরিবর্তন করার চেষ্টা করুন:

db.Leads.Where(l => l.Date.Day == date.Day
            && l.Date.Month == date.Month
            && l.Date.Year == date.Year
            && l.Property.Type == ProtectedPropertyType.Password
            && l.Property.PropertyId == PropertyId)
         .Select(l => l.Amount)
         .DefaultIfEmpty(0)
         .Sum();

এইভাবে, আপনার ক্যোয়ারি কেবল Amountক্ষেত্রটি নির্বাচন করবে । যদি সংগ্রহটি খালি থাকে তবে এটির মান সহ একটি উপাদান ফিরে আসবে 0এবং তারপরে যোগফল প্রয়োগ করা হবে।


এটি অবশ্যই কৌতুকটি করে তবে Sumএটি ডাটাবেসের পাশের পরিবর্তে প্রথমে পরিমাণ মানগুলির একটি তালিকা এবং সার্ভার সাইডে সেগুলি বেছে নেবে না ? imo 2kay এর সমাধানটি আরও অনুকূল, কমপক্ষে আরও শব্দার্থিকভাবে সঠিক।
মাকসিম ভি।

3
যখন @MaksimVI মতিন, প্রথম বাস্তবায়ন উপর ক্যোয়ারী উত্পন্ন করবে IQueryable<T>শৃঙ্খল স্টপ (সাধারণত আপনি কল যখন ToList, AsEnumerableইত্যাদি .. এবং এই ক্ষেত্রে Sum)। SumEF ক্যোয়ারিয়েবল সরবরাহকারী দ্বারা পরিচিত এবং পরিচালনা করা পদ্ধতি এবং এটি সম্পর্কিত এসকিউএল বিবৃতি উত্পন্ন করবে।
সাইমন বেলঞ্জার

@ সিমোনবেলাঞ্জার আমি সংশোধন করে দাঁড়িয়েছি, যোগফলটি ডিবি পক্ষ থেকে তৈরি করা হয়েছে, তবে এটি একটি সাবকোয়ারিতে তৈরি করা হয়েছে যা প্রথমে পরিমাণ নির্বাচন করে। মূলত কোয়েরিটি ন্যায়বিচারের SELECT SUM(a.Amount) FROM (SELECT Amount FROM Leads WHERE ...) AS aপরিবর্তে SELECT SUM(Amount) FROM Leads। এছাড়াও subquery একটি অতিরিক্ত নাল চেক এবং একটি একক সারি টেবিলের সাথে একটি অদ্ভুত বাহ্যিক জোড় আছে।
মাকসিম ভি।

উল্লেখযোগ্য পারফরম্যান্সের পার্থক্য নয় এবং এটি সম্ভবত অনুকূলিত হয়েছে, তবে আমি এখনও মনে করি যে অন্যান্য সমাধানটি আরও পরিষ্কার দেখাচ্ছে looks
মাকসিম ভি।

5
সচেতন থাকুন যে DefaultIfEmptyবেশ কয়েকটি লিনকিউ সরবরাহকারী সমর্থন করেন না তাই আপনাকে ToList()এই ক্ষেত্রে এটি ব্যবহার করার আগে একটি বা অন্য কিছু নিক্ষেপ করতে হবে যাতে এটি লিনিক টু অবজেক্টস দৃশ্যে প্রয়োগ করা যেতে পারে ।
ক্রিস্টোফার কিং

188

আমি অন্য হ্যাক ব্যবহার করতে পছন্দ করি:

double earnings = db.Leads.Where(l => l.Date.Day == date.Day
                                      && l.Date.Month == date.Month
                                      && l.Date.Year == date.Year
                                      && l.Property.Type == ProtectedPropertyType.Password
                                      && l.Property.PropertyId == PropertyId)
                          .Sum(l => (double?) l.Amount) ?? 0;

18
লিনক এসকিউএল-তে ব্যবহার করার সময় এটি গৃহীত উত্তরের চেয়ে অনেক কম এসকিউএল কোড উত্পন্ন করে
ওয়ার্টজুই

3
এটা সঠিক উত্তর. অন্য সমস্ত ব্যর্থ। প্রথমে নালাগুলিতে কাস্টিং এবং তারপরে নলের বিরুদ্ধে চূড়ান্ত ফলাফলের তুলনা করা।
মোহসেন আফশিন

3
এটি লিনক টু ইএফ-এর গৃহীত উত্তরের চেয়ে অনেক ভাল। আমার জন্য উত্পন্ন এসকিউএল ডিফল্টএফএম্পটির তুলনায় প্রায় 3.8 গুণ ভাল সম্পাদন করে।
ফ্লোরিয়ান

2
এটি অনেক দ্রুত।
ফ্রেঙ্কন

1
আমি এটিকে হ্যাক বলব না, কারণ এটি হ'ল ব্যবহারযোগ্য নালাগুলি ডিজাইন করা হয়েছে, অর্থাত কোনও ডেটা এবং ডিফল্ট মানের মধ্যে পার্থক্য দেখায়
মাইকটি


4

এটা আমার জন্য জয়:

int Total = 0;
Total = (int)Db.Logins.Where(L => L.id == item.MyId).Sum(L => (int?)L.NumberOfLogins ?? 0);

আমার লগিন টেবিলের মধ্যে, NUMBEROFLOGINS ক্ষেত্রে ক্ষেত্রের মধ্যে কয়েকটি মান শুল্ক হয় এবং অন্যদের একটি INT নম্বর থাকে। আমি এখানে এক কর্পোরেশনের (প্রতিটি আইডি) সমস্ত ব্যবহারকারীর মোট সংখ্যা


1

চেষ্টা করুন:

দ্বিগুণ উপার্জন = db.Leads.Where (l => l.ShouldBeIncused) .সুম (l => (ডাবল?) l.Amount) ?? 0 ;

" SELECT SUM ([পরিমাণ]]) " ক্যোয়ারী খালি তালিকার জন্য NULL ফিরিয়ে দেবে। তবে আপনি যদি লিনকিউ ব্যবহার করেন এটি প্রত্যাশা করে যে " যোগফল (l => l.Amount) " দ্বিগুণ ফিরে আসে এবং এটি আপনাকে " ?? " অপারেটরটিকে খালি সংগ্রহের জন্য 0 সেট করতে দেয় না ।

এই পরিস্থিতি এড়াতে আপনাকে লিনকুই " ডাবল? " আশা করতে হবে । আপনি " (ডাবল?) L.Amount " কাস্ট করে এটি করতে পারেন ।

এটি এসকিউএলে ক্যোয়ারিকে প্রভাবিত করে না তবে এটি লিনকিউকে খালি সংগ্রহের জন্য কাজ করে।


0
db.Leads.Where(l => l.Date.Day == date.Day
        && l.Date.Month == date.Month
        && l.Date.Year == date.Year
        && l.Property.Type == ProtectedPropertyType.Password
        && l.Property.PropertyId == PropertyId)
     .Select(l => l.Amount)
     .ToList()
     .Sum();

1
কোড সম্পর্কে উত্তরের জন্য দয়া করে কিছু তথ্য যুক্ত করুন
যাকেন এই’’র

1
আমি টোললিস্ট () ব্যতীত চেষ্টা করার সময় আমি ত্রুটি পেয়েছি, কারণ এটি কিছুই দেয় না। তবে ToList () খালি তালিকা তৈরি করবে এবং আমি টোললিস্ট ()। Sum () করার সময় এটি কোনও ত্রুটি দিচ্ছে না।
মোনা

2
আপনি ToListযদি চান তা যোগফল হয় তবে আপনি সম্ভবত এখানে ব্যবহার করতে চাইবেন না। এটি পুরো ফলাফল সেটটি (কেবলমাত্র Amountএই ক্ষেত্রে প্রতিটি রেকর্ডের জন্য) মেমরিতে এবং তারপরে Sum()সেই সেটটি ফিরিয়ে দেবে । এসকিউএল সার্ভারের মাধ্যমে গণনা করে এমন আরও একটি সমাধান ব্যবহার করা আরও ভাল।
জোশ এম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.