'ইন্ট 32' টাইপের মান প্রেরণায় ব্যর্থ হওয়ায় বস্তুগত মানটি নাল


192

আমার কাছে নিম্নলিখিত কোড রয়েছে। আমি ত্রুটি পাচ্ছি:

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

যখন ক্রেডিটহিসটরি সারণীর কোনও রেকর্ড নেই।

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID                                        
                  where u.ID == userID
                  select ch.Amount).Sum();

নাল মানগুলি গ্রহণ করার জন্য কীভাবে আমি কোয়েরিটি সংশোধন করতে পারি?

উত্তর:


328

একটি লিনাক-টু-এসকিএল কোয়েরি কোড হিসাবে কার্যকর করা হয় না, বরং এসকিউএল-তে অনুবাদ করা হয়। কখনও কখনও এটি একটি "ফুটো বিমূর্ততা" যা অপ্রত্যাশিত আচরণ দেয়।

এরকম একটি কেস হ'ল নাল হ্যান্ডলিং, যেখানে বিভিন্ন জায়গায় অপ্রত্যাশিত নাল থাকতে পারে। ...DefaultIfEmpty(0).Sum(0)এই (বেশ সহজ) ক্ষেত্রে সহায়তা করতে পারে, যেখানে কোনও উপাদান এবং স্ক্যুএল এর SUMরিটার্ন নাও থাকতে পারে nullযেখানে সি # 0 আশা করে।

আরও সাধারণ পদ্ধতির ব্যবহার হ'ল ??যা অনুবাদ করা হবে COALESCEযখনই যখনই ঝুঁকি থাকে যে উত্পন্ন এসকিউএল একটি অপ্রত্যাশিত নাল ফেরায়:

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select (int?)ch.Amount).Sum() ?? 0;

এই প্রথম int?সি # সংকলকটি বলতে কাস্ট করে যে এই এক্সপ্রেশনটি প্রকৃতপক্ষে ফিরে আসতে পারে null, যদিও এটি Sum()ফেরত দেয় int। তারপরে আমরা কেসটি পরিচালনা করতে সাধারণ ??অপারেটরটি ব্যবহার করি null

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


3
ধন্যবাদ আন্ডারস, ডিফল্টএফএম্পটি (0) সহ সমাধান .সুম () আমার পক্ষে ভাল কাজ করে। দ্বিতীয় সমাধানটিও (int?) দিয়ে চেষ্টা করেছি ... ?? 0 ..., তবে এটি আগের মতোই ব্যতিক্রম ছুঁড়েছে ..
zosim

অবশেষে এটি পরীক্ষা করে দেখতে পেলাম এবং এটিকে সামঞ্জস্য করলেন, সুতরাং এখন দ্বিতীয় সংস্করণটিও কাজ করে।
অ্যান্ডারস আবেল

1
খালি ডেটাসেটে প্রয়োগ করা হলে যোগফল () এবং অন্যান্য সামগ্রিক ফাংশনগুলি বাতিল হয়ে যাবে return তাদের সংজ্ঞার বিপরীতে, বাস্তবে তারা অন্তর্নিহিত ধরণের একটি অবিচ্ছিন্ন সংস্করণ ফিরিয়ে দেয়।
সানকাট 2000

2
@ রিসার্সিভ: আপনার উদাহরণ লাইনকিউ-টু-অবজেক্টস, লিনকুই-টু-এসকিউএল নয় (বা লিনকিউ-টু-সত্তা)। তাদের অন্তর্নিহিত ডেটা সরবরাহকারীরা তাদের আলাদা আচরণ করে।
সানক্যাট 2000

এটি একটি ভাল ধারণা ছিল। আমি আমার রিটার্ন অবজেক্টটি আপডেটযোগ্য বৈশিষ্ট্যগুলি হিসাবে আপডেট করেছি এবং এটি একটি কবজ হিসাবে কাজ করেছে।
ক্রেমেনা লালোভা

8

নালযোগ্য Amountক্ষেত্রটিকে অনুমতি দেওয়ার জন্য , নালগুলি 0 এ রূপান্তর করতে কেবল নাল কোয়েলসিং অপারেটরটি ব্যবহার করুন।

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch.Amount ?? 0).Sum();

1
আমি যখন আপনার টিপটি ব্যবহার করি, সংকলক বলে: অপারেটর '??' 'int' এবং 'int' টাইপের অপারেন্ডগুলিতে প্রয়োগ করা যাবে না। আমি কি কিছু ভুলে গেছি?
জোসিম

@ জোসিম: প্রথমটিতে কাস্ট যুক্ত করার কারণ এটি int?
অ্যান্ডারস হাবেল

আমি অন্তর্ভুক্ত করেছি ?, কিন্তু একই ব্যতিক্রম। আমি আপনাকে কৃতজ্ঞ করব, যখন আপনি enর্ষা হবে। এই বাক্য গঠনতে কী ভুল তা পরীক্ষা করতে।
জোসিম

1
@ জোসিম: আমি সমস্যাটি বুঝতে পারি না। যদি Amountএটি হয় intতবে আমরা ইতিমধ্যে নিশ্চিত যে এটি বাতিল হতে পারে না, এবং কোলেসিং অপ্রয়োজনীয়। আপনি যদি বলেছিলেন যে ত্রুটিটি পেয়ে Amountযাচ্ছেন, তবে এটি কেবল নমনীয় নয়, এটি কেবল একটি int, সেক্ষেত্রে আপনাকে নালাগুলির অনুমতি দেওয়ার জন্য ডিজাইনারে আপনার লিনক 2 এসকিএল ডিবিএমএল কলামটি পরিবর্তন করতে হবে।
পুনরাবৃত্তি

1
@ রিসার্সিভ: পরিমাণ হ'ল, ঠিক আছে। পরিমাণ ইতিমধ্যে মান আছে। আমি মনে করি, উপরে ত্রুটি ঘটেছে কারণ ক্রেডিটহিসটরি টেবিলটি খালি রয়েছে। আমার ব্যবহারকারীর টেবিলে একটি রেকর্ড রয়েছে এবং ক্রেডিট হিস্টরি সারণীতে 0 টি রেকর্ড রয়েছে এবং ত্রুটি ঘটেছে। আমি যখন DefaultIfEmpty (0) ব্যবহার করি .সুম () এটি ভাল কাজ করে তবে সাথে ?? 0 এটি ত্রুটি ছুড়ে ফেলে। আমার আর একটি প্রশ্ন এই ক্ষেত্রে সেরা অনুশীলন কি? DefaultIfEmpty (0)? ধন্যবাদ
zosim

4

আপনি aggregateক্রিয়াটি ব্যবহার করছেন যা ক্রিয়া সম্পাদন করতে আইটেমগুলি পাচ্ছে না, আপনাকে অবশ্যই যাচাই করতে হবে যে লিনক কোয়েরি নীচে হিসাবে কিছু ফলাফল দিচ্ছে:

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0

11
এটি এসডিভি কে দুইবার এক্সিকিউট করে। কোনটি আপনি IQueryables জন্য কি আপনি চান না
Ody

4

আমি যখন একটি ভিউ থেকে নির্বাচন করার চেষ্টা করছিলাম তখন এই ত্রুটি বার্তাটি ছিল।

সমস্যাটি হল এই দৃশ্যটি সম্প্রতি কিছু নতুন নালার সারি অর্জন করেছে (সাবস্ক্রাইবারআইডি কলামে), এবং এটি ইডিএমএক্স (ইএফ ডাটাবেস প্রথমে) আপডেট করা হয়নি।

এটির কাজ করার জন্য কলামটি নুলযোগ্য হতে হবে।

var ডিলার = প্রসঙ্গে D

রিফ্রেশ দেখার আগে:

public int SubscriberId { get; set; }

রিফ্রেশ দেখার পরে:

public Nullable<int> SubscriberId { get; set; }

EDMX এ ভিউটি মোছা এবং ফিরে যুক্ত করার কাজ করেছে।

আশা করি এটি কাউকে সাহায্য করবে।


এটি আমার ইস্যু এবং আমার উত্তর ছিল
সাইমন নিকোলস

4

আমি এই কোডটি ব্যবহার করেছি এবং এটি সঠিকভাবে প্রতিক্রিয়া জানায়, কেবলমাত্র আউটপুট মান হ'ল নয়।

var packesCount = await botContext.Sales.Where(s => s.CustomerId == cust.CustomerId && s.Validated)
                                .SumAsync(s => (int?)s.PackesCount);
                            if(packesCount != null)
                            {
                                // your code
                            }
                            else
                            {
                                // your code
                            }

1

আমি দেখতে পাচ্ছি যে এই প্রশ্নের ইতিমধ্যে উত্তর দেওয়া হয়েছে। তবে আপনি যদি এটি দুটি বিবৃতিতে বিভক্ত করতে চান তবে নিম্নলিখিতগুলি বিবেচনা করা যেতে পারে।

var credits = from u in context.User
              join ch in context.CreditHistory 
                  on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch;

var creditSum= credits.Sum(x => (int?)x.Amount) ?? 0;

0

রানটাইমের সময় এই কোডটি সহ সত্তা ফ্রেমওয়ার্ক 6 এ এই ত্রুটিটি পেয়েছেন:

var fileEventsSum = db.ImportInformations.Sum(x => x.FileEvents)

LeandroSoares থেকে আপডেট:

একক মৃত্যুদন্ডের জন্য এটি ব্যবহার করুন:

var fileEventsSum = db.ImportInformations.Sum(x => (int?)x.FileEvents) ?? 0

মূল:

এটিতে পরিবর্তন হয়েছে এবং তারপরে এটি কাজ করেছে:

var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;

1
দুইবার এটি কার্যকর করতে চান?
নওফাল

এটি একটি ভাল উত্তর নয়। এটি ডিবি থেকে দু'বার পুনরুদ্ধার করবে।
লেয়ানড্রো

@ নওফাল এটি সত্য তবে এটি রানটাইম ত্রুটির চেয়ে অনেক ভাল। আপনি একেবারে লিনক-টু-এসকিএল ব্যবহার করতে পারেন তবে ল্যাম্বদার সাথে এটি আরও শক্ত। আপনি অবশ্যই ব্যতিক্রমটি ধরতে পারেন তবে আমি মনে করি যে সমাধান দুটি মৃত্যুদণ্ডের চেয়েও খারাপ।
ওগ্লাস

@ লিন্ড্রোসোয়ারেস উপরের মন্তব্যটি দেখুন
ওগ্লাস

1
পছন্দ করুন আমি আমার উত্তর আপডেট করেছিলাম এবং আপনার প্রদত্ত কোড এবং তার পরিবর্তে কেন এটি ব্যবহার করতে হবে সেগুলি ব্যবহার করেছিলাম।
ওগ্লাস

0

আমিও একই সমস্যার মুখোমুখি হয়েছি এবং "কলামটি ব্যবহারযোগ্যভাবে নালাম হিসাবে তৈরি করার মাধ্যমে সমাধান করেছি?" অপারেটর.

Sequnce = db.mstquestionbanks.Where(x => x.IsDeleted == false && x.OrignalFormID == OriginalFormIDint).Select(x=><b>(int?)x.Sequence</b>).Max().ToString();

কখনও কখনও নাল ফিরে আসে।

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