PDA

View Full Version : سوال: تعیین DataTable برای نمایش Cross-Table Query



mmbguide
دوشنبه 31 اردیبهشت 1397, 11:06 صبح
سلام

من در برنامم به روش Typed-Dataset به بانک اطلاعاتی وصل شدم و در زمان نمایش اطلاعات همان جدول مشکلی ندارم. حالا یک Stored Procedure ایجاد کردم که حدود 3 جدول را با هم Joint میکنه و مقادیر دلخواه را نمایش میده. در خود SQL که تست میکنم مشکلینیست و درست کار میکنه ولی در برنامه خودم نمیدونم چطور باید اوم رو فراخوانی کنم و هر کاری میکنم با خطا مواجه میشم و اطلاعات با هیچ نوع از DataTableهای من همخوانی ندارد.

ممنون اگر راهنمایی کنید

Shadow_net
دوشنبه 31 اردیبهشت 1397, 11:23 صبح
سلام typed dataset همون بایندینگ سُرس هست؟ منم همین مشکل رو دارم. شما هم مثل من پروسیجر هایی که میسازید رو نمیبینید؟

mmbguide
دوشنبه 31 اردیبهشت 1397, 11:38 صبح
خیر همون نیست. در واقع اطلاعاتی که از یک جدول فراخوانی میکنید باید در Datasetی که دارای ستونهایی همنوع هستند قرارگیرند ولی از اونجایی که من اطلاعاتم از 3 جدول و بصورت Join شده فراخوانی میشوند در DataSet که توسط ویزارد برنامه تولید میشه و مطابقت با جداول بانک اطلاتیم داره، برنامه رو با خطا مواجه میکنه. خودم دارم این کار رو انجام میدم و جواب میده ولی دنبال راهی بهتر و شاید ساده تر میگردم.

خودم اینکار رو دارم انجام میدم



ابتدا یک DataTable میسازم
ستونهایی مطابق با ستون های فراخوانی شده به DataTable ایجاد شده اضافه میکنم.(با ویژگی های مورد نظر مثل ReadOnly, Unique, DataType,...)
بعد اطلاعات رو فراخوانی میکنم و در یک حلقه مقادیر ستون های فراخوانی شده را در DataTable خودم قرار می دم و در انتها به برنامه ارسال می کنم (این کار در لایه DataAccessLayer انجام میشه)

mmbguide
دوشنبه 31 اردیبهشت 1397, 12:14 عصر
یه مشکلی که دارم اینه که چطور میتونم با Loop در Stored Proceuret فراخوانی شده حرکت کنم؟

danialafshari
دوشنبه 31 اردیبهشت 1397, 12:21 عصر
با سلام
dataset رو باز کنید روی فضای خالی کلیک راست و TableAdapter رو انتخاب کنید سپس در مرحله ویزارد Stored Procedure مربوطه رو انتخاب کنید

سلام typed dataset همون بایندینگ سُرس هست؟ منم همین مشکل رو دارم. شما هم مثل من پروسیجر هایی که میسازید رو نمیبینید؟
دیتاست رو از طریق پنجره Data Sources سمت چپ Configure Data Source With Wizard... بروزرسانی کنید مشکلتون حل میشه
موفق باشید

mmbguide
سه شنبه 01 خرداد 1397, 12:05 عصر
من با این روش مشکلم رو حل کردم


public DataTable spFINGetByProjectIDv_Get(int TotalRow, int ProjectID)
{

try
{
DataTable dt = new DataTable();
DataRow dr = default(DataRow);


using (SqlConnection connection = new SqlConnection(_dbConnectionString))
{

SqlCommand command = new SqlCommand();
SqlDataReader reader = default(SqlDataReader);

command.Connection = connection; //New SqlConnection(_dbConnectionString)
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@NumberOfRows", TotalRow);
command.Parameters.AddWithValue("@ProjectID", ProjectID);
command.CommandText = "qcsFIN.spFINGetByProjectIDv";
connection.Open();

reader = command.ExecuteReader();

if (reader.HasRows)
{
int n = 1;

// Call Read before accessing data.
while (reader.Read())
{

if (n == 1)
{
n++;
for (int i = 0; i <= reader.FieldCount - 1; i++)
{
DataColumn dcColumn = new DataColumn();
dcColumn.DataType = reader.Item(i).GetType;
dcColumn.ColumnName = reader.GetName(i).ToString();
dt.Columns.Add(dcColumn);
}
}

dr = dt.NewRow;
for (int i = 0; i <= reader.FieldCount - 1; i++)
{
dr[reader.GetName(i).ToString()] = reader.Item(reader.GetName(i).ToString());
}
dt.Rows.Add(dr);
}
}
// Call Close when done reading.
reader.Close();
}


return dt;
}
catch (Exception ex)
{
throw (new Exception(ex.Message));
return null;
}
}

mmbguide
سه شنبه 01 خرداد 1397, 12:21 عصر
توضیح کد بالا


تابع من یک DataTable رو برمیگردونه
بعد اومدم دو متغیر تعریف کردم که Datatable, DataRow هستند
تا اونجایی که کد command.ExecuteReader اجرا میشه رو هم کاری نداریم و مشابه همه دستورات فراخوانی اطلاعات از بانک هستش
بعد از بررسی اینکه آیا رکورد موجود است یا خیر یک متغیر عددی تعریف کردم با نام n که مقدار اولیه اون برابر 1 است
حالا وقتی کد While reader.Read اجرا میشه در واقع نشانگر در ردیف اول قرار میگیره و حالا میتونم اطلاعات مربوط به ستون های ارسال شده از SQL رو بخونم و تنها یک بار هم این عمل انجام بشه کفایت میکنه و حالا برای اینکه برنامه به درستی کار کنه، اگر مقدار n=1 باشد عملیات تولید ستون برام انجام میشه و در حلقه ای بعدی چون مقدار n بزگتر از 1 شده دیگر کدهای داخل If اجرا نمیشه.


حلقه اول



for (int i = 0; i <= reader.FieldCount - 1; i++)
{
DataColumn dcColumn = new DataColumn();
dcColumn.DataType = reader.Item(i).GetType;
dcColumn.ColumnName = reader.GetName(i).ToString();
dt.Columns.Add(dcColumn);
}



این حلقه به تعداد فیلدهای موجود در اطلاعات ارسالی از SQL تکرار میشه
ابتدا یک متغیر از نوع ستون اطلاعات ایجاد کردم و Type و Name ستون جدید رو از خود اطلاعات دریافتی بدست میارم
در ادامه ستون جدید رو به DataTable ایجاد شده اضافه میکنم


توضیح کد زیر



dr = dt.NewRow;
for (int i = 0; i <= reader.FieldCount - 1; i++)
{
dr[reader.GetName(i).ToString()] = reader.Item(reader.GetName(i).ToString());
}
dt.Rows.Add(dr);



در این بخش یم ردیف جدید (خالی) به DataTable اضافه میکنم. ستون های DataTable در حلقه بالا ایجاد شده بودند
در هر بار اجرای حلقه While من یک ردیف به DataTable اضافه میکنم و بعد به تعداد فیلدهای موجود، فیلدهای ردیف جدید رو مقدار دهی میکنم

انشالله که توضیحاتم گنگ نبوده باشه

این روش من بود و اگر راه بهتری هست اطلاع رسانی کنید

mmbguide
سه شنبه 01 خرداد 1397, 12:23 عصر
البته کد بالا یک مشکلی داره.

در انتها که مقدار فیلدهای دریافت شده از SQL در فیلدهای جدید از DataTable قرار میگیره نتونستم عمل Convert اطلاعات رو متناسب با ستون انجام بدم و همه اونها بصورت String مقداردهی میشند

Mahmoud.Afrad
سه شنبه 01 خرداد 1397, 17:57 عصر
البته کد بالا یک مشکلی داره.

در انتها که مقدار فیلدهای دریافت شده از SQL در فیلدهای جدید از DataTable قرار میگیره نتونستم عمل Convert اطلاعات رو متناسب با ستون انجام بدم و همه اونها بصورت String مقداردهی میشند

آقای افشاری پاسخ صحیح را دادند. راه ساده تر هم درگ کردن پروسیجر از پنجره server explorer به داخل دیتاست هست.