PDA

View Full Version : سوال: اشكال در آپديت كردن كليد خارجي در LINQ



amirniknam
جمعه 24 خرداد 1387, 18:46 عصر
سلام دوستان من در LINQ تازه كار هستم و تازه 2 هفته است كه دارم روش كار مي كنم امروز به مشكلي در مورد آپديت كردن كليد هاي خارجي بر خوردم :
فرض كنيد من 2 جدول به اين صورت دارم (جداول رو همينطوري و براي امتحان ساختم):لبخندساده:

http://i32.tinypic.com/1231ch2.jpg

همنيطور كه مي بينيد MARK در جدول STUDENT يك كليد خارجي هستش براي جدول MARK من با دستور زير مي خوام ID ي MARK رو آپديت كنم :




rdataDataContext db = new rdataDataContext();
var query = from p in db.Marks
where p.ID == int.Parse(TextBox1.Text)
select p;

Mark mark = query.First();
mark.ID += 20;
db.SubmitChanges();



اما با خطاي زير مواجه مي شم (اين طور كه به نظر مياد اين خطا مربوط به خود LINQ هست و ربطي به ديتا بيس و برخورد كليد هاي خارجي نداره چون من با INSERT و DELETE مشكلي ندارم) :



Value of member 'ID' of an object of type 'Mark' changed
A member defining the identity of the object cannot be changed
Consider adding a new object with new identity and deleting the existing one instead







لطفا راهنمايي بفرماييد.

mohammad272005
جمعه 24 خرداد 1387, 19:01 عصر
mark.ID += 20;
1- ID يه primary key هست پس چه معني داره كه update بشه؟ ما معمولا مستقيما در مقداردهي primary keyها دخالت نمي كنيم.

amirniknam
جمعه 24 خرداد 1387, 19:17 عصر
ممنون از پاسختون من هم واقعا نمي خوام اين كار رو انجام بدم ولي همنوطور كه گفتم در حال يادگيري LINQ هستم به هر حال بايستي راهي براي اين كار وجود داشته باشه تو اين لينك پيشنهد كرده اول اون ENTITY رو پاك بعد يكي ديگه بساز ولي اين كار مشكلات زيادي داره
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1883394&SiteID=1

mohammad272005
جمعه 24 خرداد 1387, 19:40 عصر
شما ميخوايد يه mark جديد ايجاد كنيد؟ ميشه بگيد ميخواين چيكار كنيد؟ شما اينطوري يه كم مشكل واضحتر بشه.

Zaparo
جمعه 24 خرداد 1387, 20:19 عصر
اگه میخوای یاد بگیری با LINQ To SQL شروع نکن

amirniknam
جمعه 24 خرداد 1387, 23:41 عصر
شما ميخوايد يه mark جديد ايجاد كنيد؟ ميشه بگيد ميخواين چيكار كنيد؟ شما اينطوري يه كم مشكل واضحتر بشه.

نه من قصد ايجاد مارك جديد رو ندارم فقط مي خوام فيلد ID يك ركورد در جدول MARK رو تغيير بدم اما با اين كار LINQ به خاطر تغيير Identity ايراد ميگيره در واقع مي خوام يك كليد اصلي رو تغيير بدم اونطور كه توي document هاي مايكروسافت كه همراه VS 2008 نصب ميشه خوندم هر ركورد كه فراخواني مي شود يك Identity به اون نسبت مي ده كه در واقع شناسه اي براي entity هستش من اول فكر مي كردم اين خطا به خاطر برخورد كليد خارجي به وجود آمده كه البته الان متوجه شدم كلا به خاطر آپديت كليد اصلي است در واقع سوالم رو بايد اصلاح كنم :چطوري ميشه يك كليد اصلي رو آپديت كنم ؟


اگه میخوای یاد بگیری با LINQ To SQL شروع نکن

پيشنهاد شما چيه ؟ لطفا منبع رو هم معرفي كنيد (البته من غير از اين مورد تويه قسمت هاي ديگه هم مقداري كار كردم)

linux
جمعه 24 خرداد 1387, 23:46 عصر
نه من قصد ايجاد مارك جديد رو ندارم فقط مي خوام فيلد ID يك ركورد در جدول MARK رو تغيير بدم اما با اين كار LINQ به خاطر تغيير Identity ايراد ميگيره در واقع مي خوام يك كليد اصلي رو تغيير بدم اونطور كه توي document هاي مايكروسافت كه همراه VS 2008 نصب ميشه خوندم هر ركورد كه فراخواني مي شود يك Identity به اون نسبت مي ده كه در واقع شناسه اي براي entity هستش من اول فكر مي كردم اين خطا به خاطر برخورد كليد خارجي به وجود آمده كه البته الان متوجه شدم كلا به خاطر آپديت كليد اصلي است در واقع سوالم رو بايد اصلاح كنم :چطوري ميشه يك كليد اصلي رو آپديت كنم ؟

پيشنهاد شما چيه ؟ لطفا منبع رو هم معرفي كنيد (البته من غير از اين مورد تويه قسمت هاي ديگه هم مقداري كار كردم)
کلید اصلی اگر از نوع auto number باشه که نمی توانی اصلاح کنید در غیر این صورت هم اول باید تمام رکورد های زیر مجموعه این کلید را پاک کنی و بعد این رکورد را پاک کنی یک رکورد جدید با کلید جدید و اطلاعات رکورد قبلی بسازی و بعد رکوردهای زیر مجموعه را با کلید جدید اضافه کنی .
چه احتیاجی هست که حالا کلید اصلی را آپدیت کنی؟

amirniknam
شنبه 25 خرداد 1387, 07:14 صبح
کلید اصلی اگر از نوع auto number باشه که نمی توانی اصلاح کنید در غیر این صورت هم اول باید تمام رکورد های زیر مجموعه این کلید را پاک کنی و بعد این رکورد را پاک کنی یک رکورد جدید با کلید جدید و اطلاعات رکورد قبلی بسازی و بعد رکوردهای زیر مجموعه را با کلید جدید اضافه کنی .

بله حق با شماست اما اگر اجازه بديم كه ديتا بيس Cascading Update رو انجام بده نيازي به اين كار نيست اما مشكل اينجاست كه LINQ اجازه نمي ده كه كار به ديتا بيس برسه و همون اول به خاطر Identity خطا مي گيره


چه احتیاجی هست که حالا کلید اصلی را آپدیت کنی؟

در بسياري از جداول من با شما موافقم و نيازي به اين كار نيست اما تصور كنيد كليد اصلي شما در يك جدول به عنوان مثال شماره دانشجويي هستش خوب اپراتور ممكنه شماره رو اشتباه وارد كنه بنابراين بايستي امكان اصلاح براش وجود داشته باشه . مگر آنكه شما از كليد اصلي تنها به منظور شماره سطر استفاده كنيد اونوقت لازم هست بي جهت براي تمام جداولتون يك فيلد اضافي داشته باشيد مثلا مي خواهين گروه كاري تعريف كنين خوب به عنوان مثال هر گروه يك كد و يك نام دارد و شما دوست داريد به كاربرتون اين اجازه رو بديد كه كد هاي گروه رو خودش تعيين كنه (مثلا براي يك سازمان يا اداره ممكنه كد هاي گروه كاري مشخص باشه و كاربر دوست داشته باشه همون كد ها رو در برنامه بزاره ) بنابراين شما 2 راه داريد يا PK رو همون كد گروه در نظر ميگيريد كه به مشكل من بر ميخوريد چون بايد امكان اصلاح باشه يا PK رو مثلا شماره سطر در نظر گرفته و كد گروه رو شاخص قرار ميديد منتها در اين حالت بي جهت فيلد اضافه داريد .