PDA

View Full Version : سوال: مشکل با خروجی متد Sqldatareader



RezaNrzdh
شنبه 11 خرداد 1392, 20:22 عصر
سلام و خسته نباشید خدمت اساتید بزرگوار.

والا من یه متد نوشتم برای واکشی اطلاعات از دیتابیس اما به مشکل خوردم.
به طور مختصر کد رو توضیح میدم.

متد رو public گرفتم و نوعش رو هم Sqldatareader قرار دادم...ورودی های به متد هم به قرار زیر هست


commandType که عملا ارتباط با Stored procedure رو برقرار میکنه
Command text که اسم Stored procedure رو تعیین میکنه
و sqlparameters که پرامتر های برای واکشی رو مشخص میکنه

مشکل من زمانی هست که میخوام عمل واکشی رو انجام بدم و در نهایت return


این قسمت انتهایی متد هست

if (dr.Read())
{
for (int i = 0; i < dr.FieldCount; i++)
{
values = dr.GetValue(i);
}
}
dr.Close();
con.Close();

return values;

اگر بیام متغیر values رو از نوع Sqldatareader بگیرم...کد داخل حلقه For خطا میده که dr.getvalue از نوع object هست و شما نمیتونید در sqldatareader بریزید.
اگر بیام values رو به صورت []object در نظر بگیرم ، مشکل کد داخل حلقه برطرف میشه...اما چون متدم از نوع sqldatareader هست...زمان return خطا میده که متد شما sqldatareader هست و نمیتونید به صورت object اطلاعات رو بفرستین بیرون.


راه درست به نظر شما چی هستش؟؟؟البته خودم با یک روش به جواب رسیدم اما نمیدونم درسته یا نه؟؟؟ اونم اینه که نوع متدم رو و تمام متد هایی که این متد رو صدا میزنن []object و یا []string بگیرم.

tooraj_azizi_1035
شنبه 11 خرداد 1392, 21:32 عصر
using System;
using System.Data;
using System.Data.SqlClient;


class Program
{
static void Main()
{
string str = "Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=SSPI";
ReadOrderData(str);
}

private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";

using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();

SqlDataReader reader = command.ExecuteReader();

// Call Read before accessing data.
while (reader.Read())
{
ReadSingleRow((IDataRecord)reader);
}

// Call Close when done reading.
reader.Close();
}
}

private static void ReadSingleRow(IDataRecord record)
{
Console.WriteLine(String.Format("{0}, {1}", record[0], record[1]));
}

}

RezaNrzdh
شنبه 11 خرداد 1392, 21:51 عصر
ممنون از توجهت دوست عزیز...این کد رو دیده بودم اما متوجه نشدم دقیق کارشو.
این الان چجوری اطلاعات واکشی شده رو میفرسته بیرون؟

vira1368
شنبه 11 خرداد 1392, 22:34 عصر
به جای این خط

values = dr.GetValue(i);

میتونید اینطور بنویسید

values = dr[i];

اینطور مقدار SqlDataReader در value ریخته میشه و return هم مشکل نداره.

RezaNrzdh
شنبه 11 خرداد 1392, 22:58 عصر
مشکل حل نشد دوست عزیز.
بنده کدم رو اینجا قرار میدم

public SqlDataReader ExecuteReader(CommandType cmdtype, string cmdtxt, params SqlParameter[] cmdparameters)
{
SqlConnection con = new SqlConnection(ConnectionString());
SqlCommand cmd = new SqlCommand();

cmd.Connection = con;
cmd.CommandType = cmdtype;
cmd.CommandText = cmdtxt;
cmd.Parameters.AddRange(cmdparameters);

SqlDataReader dr;

con.Open();
dr = cmd.ExecuteReader();
SqlDataReader values;

if (dr.Read())
{
for (int i = 0; i < dr.FieldCount; i++)
{
values = dr[i];
}
}
dr.Close();
con.Close();

return values;

RezaNrzdh
سه شنبه 14 خرداد 1392, 11:11 صبح
سلام...من مشکلم رو حل کردم...اما یه سوال داشتم.

راهی که رفتم اینطور هست که عملا من دیگه دونه دونه داخل این متد فیلد های fetch شده رو بررسی نمیکنم...همین که ExecuteReader اتفاق افتاد و اطلاعات وارد dr شد...میام همون dr رو return میکنم...و در لایه BLL میام از IDataReader استفاده میکنم و اطلاعات رو به UI میفرستم. و کاملا جواب میده و عمومیت متد هم پا بر جا میمونه...

اما...

مشکل اینجاست که وقتی بخوام dr رو return کنم...دیگه نباید کانکشنم رو close کنم...چون با این کار اطلاعات fetch شده ازبین میرن...حالا سوالم اینجاست که نبستن کانکشن اشکالی نداره؟مشکلی ایجاد نمیکنه؟؟؟البته واسه رفع این مشکل اومدم توی همین متد یه شرط گذاشتم ، که اگه کانکشن باز باشه کانکشن رو ببنده و واکشی بعدی اتفاق نیفته...اگه باز نبود واکشی بعدی صورت بگیره...حالا باز سوال اینه...باز بودن کانکشن تا فراخوانی دوباره متد...ایرادی نداره؟

شما چه راهی پیشنهاد میکنید؟

اینم از تغییر کدم:

public SqlDataReader ExecuteReader(CommandType cmdtype, string cmdtxt, params SqlParameter[] cmdparameters)
{
SqlConnection con = new SqlConnection(ConnectionString());
SqlCommand cmd = new SqlCommand();

cmd.Connection = con;
cmd.CommandType = cmdtype;
cmd.CommandText = cmdtxt;
cmd.Parameters.AddRange(cmdparameters);
SqlDataReader dr = null;

try
{
if (con.State != ConnectionState.Open)
{
con.Open();
}
else
{
con.Close();
}
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection) ;
}
catch(Exception)
{
con.Close();
}
return dr;
}