1398-03-19 13:39 خطا در هنگام ثبت در دیتابیس
zahmah

 
سلام
کد ثبت من در دیتابیس به صورت زیر هست:
tbl_SendData tbl = new tbl_SendData() ;
tbl.dataCode = GetData_ID ;
tbl.title = txtTitle.Text ;
tbl.Address = txtDestination.Text ;
tbl.Milbase = chkList_MilBase.CheckedItems[i].ToString() ;
Mydb.tbl_SendData.Add(tbl) ;
Mydb.SaveChanges();


جدول اس کیو ال هم به شکل زیر هستش
Send_ID int
dataCode bigint
title nvarchar(80)
Address nvarchar(150)
UserSaver nvarchar(50)
Milbase nvarchar(60)
SendDate nvarchar(30)

که بجز فیلد اول بقیه Allow Null هستند

موقع اجرا خطای زیر رو نشون میده:
System.Data.Entity.Core.EntityCommandExecutionException' occurred in EntityFramework.SqlServer.dll but was not handled in user code Exception

و در بررسی جزئیات خطا هم مطلب زیر رو نوشته:
An error occurred while starting a transaction on the provider connection. See the inner exception for details

اگه لطف کنین راهنمایی کنین
1398-03-19 17:33
حاجی شریفی
مؤسس سایت
 
سلام
همانطورکه در متن خطا اشاره شده (... inner exception ...) برای اطلاعات دقیق تر باید به InnerException مراجعه کنید.

یعنی یک try-catch دور دستورات تان قرار دهید، چیزی شبیه این:
try 
{
//...any code ...
}
catch (Exception ex)
{
if (ex.InnerException != null) ex = ex.InnerException;
string real_message = ex.Message;
}


آنگاه به هرنحوی که میتوانید مقدار real_message را چاپ یا مشاهده کنید.
(دستور چاپ و یا مشاهده در Console و WinForm و Wpf و ASP.Net و... متفاوت است ولی گمانم این بخش را بلد باشید ...)

اگر به متن خطای واقعی در real_message نگاه کنید، چه بسا خودتان سریع متوجه مشکل بشوید و به کمک دیگری هم نیاز نداشته باشید.
ولی اگر متوجه نشدید متن اصلی را اینجا قرار دهید تا بتوانم کمک دقیق تری کنم.
موفق باشید.
1398-03-19 19:51
zahmah

 
بسیار ممنون از راهنمائی تون.
خطایی که توی try cacth بهم نشون میده اینه:
New transaction is not allowed because there are other threads running in the session

که ترجمه شو میفهمم چه میگه ولی نمیدونم مشکل از کجاست.

البته ناگفته نماند من قبل از عملیات ثبت توی جدولم، عملیات جستجویی را درون جدول دیگری انجام داده ام(درون همین قطعه کد)

در ضمن عملیات ثبت در جدول دیتابیس درون یک حلقه است(یعنی توی این قطعه کد چند رکورد جدید باید در جدول ثبت شود)
1398-03-20 00:04 دلیل و حل خطای other threads running in the session
حاجی شریفی
مؤسس سایت
 
سلام
این خطا یعنی اینکه DbContext شما در جای دیگر درگیر است.
این اتفاق در دوحالت رخ میدهد.

اول) برنامه های چند-ریسمانه که در یک زمان چند تکه از کد در حال اجرا است و در واقع درستش آن است که هر بخش و ریسمان DbContext مجزای خودش را داشته باشد.

دوم) برنامه شما به صورت تودرتو یا بیرون حلقه و داخل حلقه در حال استفاده از DbContext است ، که با توضیحات تان مشکل شما از همین نوع است .

var  iqueryable_data = dbContext1.Table.Where(...).GroupJoin(...).Take(...)...;

foreach (var row in iqueryable_data)
{
//... any code ...
dbContext1.SaveChanges(); //Error
}


در کد بالا روی یک شی IQueryable حلقه read اطلاعات ایجاد کرده ایم ولی در همان حلقه در حال write اطلاعات هستیم.
به صورت عادی شما نمیتوانید از یک DbContext در دو کار همزمان و قبل از پایان قبلی استفاده کنید.

سه راه حل ساده میتوان مطرح کرد:
راه حل اول) از دو عدد DbContext مجزا استفاده کنید
var  iqueryable_data = dbContext1 .Table.Where(...).GroupJoin(...).Take(...)...;

foreach (var row in iqueryable_data)
{
//... any code ...
dbContext2 .SaveChanges(); //OK
}


راه حل دوم) عملیات read قبلی را با ToList پایان دهید.

var  ilist_data = dbContext1.Table.Where(...).GroupJoin(...).Take(...)...ToList()  ;

foreach (var row in ilist_data)
{
//... any code ...
dbContext1.SaveChanges(); //OK
}

فرمان ToList تمام اطلاعات را میخواند و کار خواندن اطلاعات را تمام میکند و DbContext برای اعمال بعدی آزاد میشود.

در واقع ToList یک foreach مجزا را اجرا میکند که اطلاعات را میخواند، شبیه این کد

شما نیاز به نوشتن این کد ندارید، این کد فقط برای فهم اتفاق صحیحی است که باید رخ دهد
var iqueryable_data = dbContext1.Table.Where(...).GroupJoin(...).Take(...)...;

//Start read from dbContext1
//ToList
var ilist_data = new List<...>();
foreach (var row in iqueryable_data)
ilist_data.Add(row);

//End read from dbContext1

//Start write from dbContext1
foreach (var row in ilist_data)
{
//... any code ...
dbContext1.SaveChanges();
}
//End write from dbContext1


راه حل سوم) چرا فقط یک خط دستور نهایی SaveChanges را به بیرون حلقه منتقل نمیکنید تا read تمام شده باشد.
بدین شکل، تمام تغییرات هم در یک واحد تراکنشی به دیتابیس ارسال شده و انجام میشود.
var  iqueryable_data = dbContext1.Table.Where(...).GroupJoin(...).Take(...)...;

foreach (var row in iqueryable_data)
{
//... any code ...
}
dbContext1.SaveChanges(); //OK


موفق باشید.
1398-03-20 16:44
zahmah

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

قطعه کد من که اصلاح شد کارش اینه که از یک چک لیست باکس، آیتمهایی رو که تیک خورده اند را در جدولی ثبت کنه(به اضافه محتویات کنترلهای دیگری در فرم که تکست باکس هستند)
namespace Data_Management
{
public partial class frmGet : Form
{
DataManagementEntities Mydb = new DataManagementEntities() ;

public frmGet()
{
InitializeComponent() ;
}

private void frmGet_Load(object sender, EventArgs e)
{
var bases = (from mb in Mydb.tbl_Base select mb);
foreach (var p in bases)
{
chkList_Base.Items.Add(p.Name_Farsi, CheckState.Unchecked) ;
lstbase.Items.Add(p.Name_Latin) ;
}
}


private void btnSaveInSendTable_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;

foreach (string itm in chkList_Base.CheckedItems)
{
tbl_SendData tblsend = new tbl_SendData() ;

tblsend.title = txtTitle.Text;

tblsend.Address = txtDestination.Text;

tblsend.base = itm;

Mydb.tbl_SendData.Add(tblsend) ;
}
Mydb.SaveChanges() ;

Cursor.Current = Cursors.Default;
}
}


اما حالا موقع اجرای btnSaveInSendTable_Click خطای زیر رو میده
An error occurred while updating the entries. See the inner exception for details
1398-03-21 00:38
حاجی شریفی
مؤسس سایت
 
سلام
از ظاهر این بخش کدهایتان خطای مشخصی پیدا نیست، فعلا آن خط که var bases = (from دارد را به صورت زیر اصلاح کنید و نتیجه را امتحان کنید.
var bases = Mydb.tbl_Base.ToList() ;


آیا این کل کد frmGet است؟ در صورت ادامه مشکل کل کد frmGet را بفرستید.
برنامه تان فرم دیگری هم دارد؟
موفق باشبد.
1398-03-22 00:19
zahmah

 
سلام ببخشید!
مشکل حل شد
حق با شما بود کدها مشکلی نداشتند. مشکل از جدول دیتابیس بود. توی اسکیوال یک فیلد کلید براش تعریف کرده بودم ولی رفتم توی Solution Explorer در قسمت مدل Entity که برای ارتباط با دیتابیس ساخته بودم دیدم دو تا فیلد کلید داره. نمیدونم چرا؟؟؟

راهنمایی تون معرکه س! چند فروم دیگه هم پست گذاشتم ولی راهنمایی شما خیلی خیلی عالی بود.
مدتی پیش هم که پست گذاشتم فقط فروم شما تونست مشکلمو حل کنه

دمتون گرم! انشاءالله استادتر بشین!!!