'System.DBNull' টাইপ করতে 'System.String` টাইপ করার জন্য বস্তুটি কাস্ট করতে অক্ষম `


109

আমি আমার অ্যাপ্লিকেশন উপরের ত্রুটি পেয়েছি। মূল কোডটি এখানে

public string GetCustomerNumber(Guid id)
{
     string accountNumber = 
          (string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp, 
                          CommandType.StoredProcedure, 
                          "GetCustomerNumber", 
                          new SqlParameter("@id", id));
     return accountNumber.ToString();
 }

আমি সঙ্গে প্রতিস্থাপন

public string GetCustomerNumber(Guid id)
{
   object accountNumber =  
          (object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM, 
                                CommandType.StoredProcedure, 
                                "spx_GetCustomerNumber", 
                                new SqlParameter("@id", id));
    if (accountNumber is System.DBNull)
    {
       return string.Empty;
    }
    else
    {
       return accountNumber.ToString();
    }
}

এর কাছাকাছি আরও ভাল উপায় আছে?


2
আপনার @ রিং এর উত্তরটি সত্যই লক্ষ্য করা উচিত, দীর্ঘমেয়াদে আপনার প্রচুর সময় সাশ্রয় ঘটবে
রোমান এম

উত্তর:


90

একটি সংক্ষিপ্ত ফর্ম ব্যবহার করা যেতে পারে:

return (accountNumber == DBNull.Value) ? string.Empty : accountNumber.ToString()

সম্পাদনা: এক্সিকিউটসকালারের দিকে মনোযোগ দেয়নি। যদি ক্ষেত্রটি প্রত্যাবর্তনের ফলাফলের অনুপস্থিত থাকে তবে এটি সত্যিই নালায় ফিরে আসে। পরিবর্তে ব্যবহার করুন:

return (accountNumber == null) ? string.Empty : accountNumber.ToString() 

3
পদ্ধতি কাজ করে না - "accountNumber" হয় না একটি ডাটাবেস মান কিন্তু একটি নিয়মিত পুরাতন প্লেইন প্রাচীন .NET "বস্তু" উদাহরণ হিসেবে বলা যায় - আপনি স্বাভাবিক "নাল" মান বিরুদ্ধে চেক করতে হবে। DBNull.Value একটি SklDataReader বা স্কেলপ্যারামিটারের জন্য কাজ করবে - তবে এখানে এই বস্তুর জন্য নয়।
marc_s

আপনি ঠিক বলেছেন, আমি কন্ডিশনের চেক অংশটি অনুকূল করতে শুরু করেছি, আগে লাইনটির দিকে নজর নেই। আমার কুলপা।
ব্যবহারকারী

আপনার পোস্টে টাইপ আছে যে আমি সত্যিই সম্পাদনা করতে পারি না কারণ সম্পাদনাটির পরিবর্তনের জন্য 6 টি অক্ষর প্রয়োজন। কেউ নাম্বার নাম্বার.টস স্ট্রিং () অ্যাকাউন্টে নাম্বার.টসস্ট্রিং () এ পরিবর্তন করতে পারেন
এরিক

@marc_s ডিবি / ক্যোয়ারী লেআউটের উপর নির্ভর করে আপনাকে তাদের উভয় বা এমনকি উভয়ের বিরুদ্ধে পরীক্ষা করা উচিত। কোথায় কোন সারি সাথে মেলে না, তাহলে আপনি একটি পাবেন null, যদি নির্বাচিত সারি হয়েছে NULLযে কলামে ফেরত মান হয় System.DBNull
আলেকজান্ডার

প্রথম ক্ষেত্রে @ আলেকজান্ডার উল্লেখ করেছেন-কোনও সারি মিলছে না - আপনি কনভার্টের উপর নির্ভর করতে পারেন। টু স্ট্রিং বা অন্য কোনও রূপান্তর পদ্ধতির উপর নির্ভর করতে পারেন যদি নাল থেকে রূপান্তর করার সময় তারা ফিরে আসার মানটি দিয়ে ভাল থাকেন: স্ট্রিংয়ের জন্য খালি স্ট্রিং, 0 টি সংখ্যার মানের জন্য মিথ্যা বুলিয়ান-এর জন্য, MINVALUE জন্য তারিখসময় ... msdn.microsoft.com/en-us/library/vstudio/...
জেইমি

199

একটি সাধারণ জেনেরিক ফাংশন দিয়ে আপনি এটি খুব সহজ করে তুলতে পারেন। শুধু এটি করুন:

return ConvertFromDBVal<string>(accountNumber);

ফাংশন ব্যবহার:

public static T ConvertFromDBVal<T>(object obj)
{
    if (obj == null || obj == DBNull.Value)
    {
        return default(T); // returns the default value for the type
    }
    else
    {
        return (T)obj;
    }
}

1
হ্যাঁ, এর মতো একটি ফাংশনই একমাত্র ব্যবহারিক সমাধান। যে কোনও ধরণের ইন-লাইন যুক্তি এটি হাজার বার অনুলিপি করে আটকে দেওয়ার পরে ব্যর্থ হবে। :-)
খ্রিস্টান হেইটার

3
আপনি যদি 1 টি কে রূপান্তরিত করতে চেষ্টা করেন তবে এটি কার্যকর হবে না (রূপান্তর করুন। টুবুলিয়ান (1) ভাল কাজ করে)
রোমান এম

@ আরমান: সুতরাং আমরা আমাদের বুলিয়ান ধরণের জন্য যাচাই করার আগে (নাল পরীক্ষা করার আগে) একটি অতিরিক্ত চেক
চাইব

1
আপনি যদি কনভার্ট ফাংশনগুলি চান বা ব্যবহার করতে চান তবে এটি কাজ করছে না। বেশ কয়েকটি পরিস্থিতি রয়েছে যেখানে আপনি সম্ভবত একটি সুস্পষ্ট কাস্টে রূপান্তর করতে পছন্দ করতে পারেন। @ রোমান তাদের মধ্যে একটি উল্লেখ করেছেন। আর একটি হ'ল আপনি যখন দশমিকের সাথে কাজ করেন এবং বিভিন্ন গোলাকার প্রক্রিয়াগুলি যত্নবান হন যা রূপান্তর করে int নিকটতম যুগ্ম মান সাবেক চক্রের, যখন স্পষ্ট ঢালাই শুধু মান কাটছাঁট করে: stackoverflow.com/questions/1608801/... যদি সম্ভব হয়, আমি মিশ্রণ থেকে NULLs মানের, টি-এসকিউএল ISNULL ফাংশন ব্যবহার করে নিষ্কাশন হবে
জেইমি

2
@ জাইম এই ফাংশনটি কোনও এসকিউএল ডেটা টাইপ থেকে সি # /। নেট ডেটা টাইপের ক্ষেত্রে অন্তর্ভুক্ত কাস্টের মতো কাজ করার কথা। যদি আপনার একটি সুস্পষ্ট কাস্টের প্রয়োজন হয় তবে এই ফাংশনটি ব্যবহার করবেন না - পরিবর্তে এটি স্পষ্টভাবে করুন।
মূক্ত

17

এক্সিকিউটিস্ক্যালার ফিরে আসবে

  • কোনও ফলাফল সেট না হলে নাল
  • অন্যথায় ফলাফলসেটের প্রথম সারির প্রথম কলাম, যা ডিবিএন হতে পারে।

আপনি যদি জানেন যে রেজাল্টসেটের প্রথম কলামটি একটি স্ট্রিং, তারপরে সমস্ত ঘাঁটিটি coverাকতে আপনাকে নাল এবং ডিবিএনুল উভয়ের জন্য পরীক্ষা করতে হবে। কিছুটা এইরকম:

object accountNumber = ...ExecuteScalar(...);
return (accountNumber == null) ? String.Empty : accountNumber.ToString();

উপরের কোডটি DBNull.ToString একটি খালি স্ট্রিং প্রত্যাবর্তনের উপর নির্ভর করে।

যদি অ্যাকাউন্ট নাম্বারটি অন্য রকম ছিল (পূর্ণসংখ্যাটি বলুন), তবে আপনাকে আরও সুস্পষ্ট হওয়া দরকার:

object accountNumber = ...ExecuteScalar(...);
return (accountNumber == null || Convert.IsDBNull(accountNumber) ?     
         (int) accountNumber : 0;

যদি আপনি নিশ্চিতভাবে জানেন যে আপনার রেজাল্টটিতে সর্বদা কমপক্ষে একটি সারি থাকবে (যেমন নির্বাচন করুন COUNT (*) ...) তবে আপনি চেকটি বাতিল করতে পারবেন।

আপনার ক্ষেত্রে ত্রুটি বার্তা "টাইপ 'সিস্টেম.ডিবনল' টাইপ করতে 'সিস্টেম.স্ট্রিং`' টাইপ করার জন্য অক্ষম" এটি নির্দেশ করে যে আপনার ফলাফল সেটটির প্রথম কলামটি একটি ডিবিএনউল মান। এটি প্রথম লাইনে কাস্ট থেকে স্ট্রিং পর্যন্ত রয়েছে:

string accountNumber = (string) ... ExecuteScalar(...);

মার্ক_স এর মন্তব্য যে আপনার ডিবিএনল যাচাই করার দরকার নেই al মূল্য ভুল।


আমার ফলসেটটি সর্বদা একটি সারিতে ফিরে আসবে না।
সাইফ খান 21

6

আপনি সি # এর নাল কোলেসিং অপারেটরটি ব্যবহার করতে পারেন

return accountNumber ?? string.Empty;

-1: এটি সংকলন করবে না: পদ্ধতিটি একটি স্ট্রিং দেয় এবং অ্যাকাউন্ট নাম্বার একটি বস্তু।
জো

2
Cmd.ExecuteScalar ()। ToString () ?? String.Empty;
চৈতন্য

Cmd.ExecuteScalar () ফিরিয়ে দিন। ToString () আমার হয়ে কাজটি করেছে
তারান

3

এই সমস্যাটি সমাধানের জন্য আরও একটি উপায় রয়েছে। আপনার স্টোর পদ্ধতিটি কীভাবে সংশোধন করবেন? ইসনুল (আপনার ক্ষেত্র, "") এসকিএল ফাংশন ব্যবহার করে, যদি ফেরতের মানটি শূন্য থাকে তবে আপনি খালি স্ট্রিংটি ফিরিয়ে দিতে পারেন।

তারপরে আপনার আসল সংস্করণ হিসাবে আপনার পরিষ্কার কোড রয়েছে।


3

এটি এমন জেনেরিক পদ্ধতি যা আমি কোনও ডিবিএনল হতে পারে এমন কোনও বস্তুকে রূপান্তর করতে ব্যবহার করি al মূল্য:

public static T ConvertDBNull<T>(object value, Func<object, T> conversionFunction)
{
    return conversionFunction(value == DBNull.Value ? null : value);
}

ব্যবহার:

var result = command.ExecuteScalar();

return result.ConvertDBNull(Convert.ToInt32);

খাটো:

return command
    .ExecuteScalar()
    .ConvertDBNull(Convert.ToInt32);

2

আমি মনে করি আপনি এটি এটি করতে পারেন:

string accountNumber = DBSqlHelperFactory.ExecuteScalar(...) as string;

যদি অ্যাকাউন্ট নাম্বার নাল হয় তবে এর অর্থ এটি DBNull স্ট্রিং নয় :)


অথবা return (accountNumber as string) ?? string.Empty;, অ্যাকাউন্ট নাম্বারটি এখনও একটি হিসাবে রয়েছে object। আপনি যদি নিজের ডাটাবেস কলটিকে নিজের লাইনে রাখতে পছন্দ করেন।
ব্রায়ান

1

স্ট্রিং.কনক্যাট ডিবিএন এবং নাল মানকে একটি খালি স্ট্রিংয়ে রূপান্তর করে।

public string GetCustomerNumber(Guid id)
{
   object accountNumber =  
          (object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM, 
                                CommandType.StoredProcedure, 
                                "spx_GetCustomerNumber", 
                                new SqlParameter("@id", id));

    return String.Concat(accountNumber);

 }

তবে, আমি মনে করি আপনি কোড বোধগম্যতার জন্য কিছু হারিয়েছেন lose


1
লিখলে কী হয় return "" + accountNumber;?
জেভ স্পিটজ

0

যেহেতু আমি একটি উদাহরণ পেয়েছি যা নাল নয় এবং আমি DBNULL এর সাথে তুলনা করলে আমি পেয়েছি Operator '==' cannot be applied to operands of type 'string' and 'system.dbnull' এবং যদি আমি নুলের সাথে তুলনা করার চেষ্টা করি তবে এটি কেবল কার্যকর হয়নি (যেহেতু ডিবিএনল একটি বস্তু) এমনকি এটি গ্রহণযোগ্য উত্তরও।

আমি কেবল 'is' কীওয়ার্ডটি ব্যবহার করার সিদ্ধান্ত নিয়েছি। সুতরাং ফলাফল খুব পঠনযোগ্য:

data = (item is DBNull) ? String.Empty : item


-1

আমি আমার জন্য এই সমস্যাটি দূর করতে একটি এক্সটেনশন ব্যবহার করি যা আপনার পরে যা হতে পারে বা নাও পারে।

এটা এইভাবেই চলে:

public static class Extensions
{

    public String TrimString(this object item)
    {
        return String.Format("{0}", item).Trim();
    }

}

বিঃদ্রঃ:

এই এক্সটেনশনটি মান ফেরায় নাnull ! আইটেমটি যদি হয় nullবা DBNull.Value , এটি একটি খালি স্ট্রিং ফিরে আসবে।

ব্যবহার:

public string GetCustomerNumber(Guid id)
{
    var obj = 
        DBSqlHelperFactory.ExecuteScalar(
            connectionStringSplendidmyApp, 
            CommandType.StoredProcedure, 
            "GetCustomerNumber", 
            new SqlParameter("@id", id)
        );
    return obj.TrimString();
}

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