PDA

View Full Version : خطا در اپدیت کلید اصلی



ali-kh
پنج شنبه 15 خرداد 1393, 18:50 عصر
با سلام
من توی entity framewok با کد زیر
mymodelEntities anb = new mymodelEntities();
dgYear.ItemsSource = anb.f_year.ToList();

اطلاعات رو توی دیتا گرید نشان میدم
و با یک کلید
anb.SaveChanges();

اطلاعات رو ذخیره میکنم
وقتی چیزی add میکنم یا اپدیت میکنم مشکلی نیست ذخیره هم میشه
ولی وقتی اون فیلد کلید اصلی باشه خطا میده که کلید اصلی نمیتونه اپدیت بشه
ولی از لجاظ منطقی این کار باید بشه
توی sql این کار رو خیلی راحت میشه کرد.
لطفا راهنمایی بفرمایید

mehdi.mousavi
جمعه 16 خرداد 1393, 05:27 صبح
با سلام من توی entity framewok با کد زیر اطلاعات رو توی دیتا گرید نشان میدم و با یک کلید اطلاعات رو ذخیره میکنم وقتی چیزی add میکنم یا اپدیت میکنم مشکلی نیست ذخیره هم میشه ولی وقتی اون فیلد کلید اصلی باشه خطا میده که کلید اصلی نمیتونه اپدیت بشه ولی از لجاظ منطقی این کار باید بشه توی sql این کار رو خیلی راحت میشه کرد. لطفا راهنمایی بفرمایید

سلام.
شما نمیتونید از طریق EF، کلید اصلی رو Update کنید. اگر واقعا این کاری هستش که باید انجام بدید (که البته، بطور کلی، بهتره در بیشتر شرایط ازش پرهیز بشه)، می تونید Stored Procedure ای بنویسید که اینکارو براتون انجام بده، سپس اون SP رو از طریق EF فراخوانی کنید. فقط هنگام نوشتن SP ی مربوطه به این نکته دقت کنید که اگر کلید اصلی در جداول دیگه Reference شده باشه، اونها رو هم باید Update کنید.

موفق باشید.

ali-kh
جمعه 16 خرداد 1393, 08:39 صبح
سلام.
شما نمیتونید از طریق EF، کلید اصلی رو Update کنید. اگر واقعا این کاری هستش که باید انجام بدید (که البته، بطور کلی، بهتره در بیشتر شرایط ازش پرهیز بشه)، می تونید Stored Procedure ای بنویسید که اینکارو براتون انجام بده، سپس اون SP رو از طریق EF فراخوانی کنید. فقط هنگام نوشتن SP ی مربوطه به این نکته دقت کنید که اگر کلید اصلی در جداول دیگه Reference شده باشه، اونها رو هم باید Update کنید.

موفق باشید.

خیلی ممنون از پاسختون

یک سوال دیگر
کدامیک از این حالات بهتره؟
انتخاب فیلد های یک جدول به عنوان کلید اصلی؟
یا اینکه برای هر جدولی یک فیلد id به عنوان کلید اصلی انتخاب کنیم که خاصیت auto incriment هم داره که در این صورت مارو از اپدیت کلید اصلی بی نیاز میکنه

چون واقعا بعضی مواقع اپدیت کلید اصلی نیازه
مثلا یک فرد با کد کارمندی که کد کارمندی اون کلید هست اگر بخواییم کد کارمندی رو تغییر بدیم لازم میشه یا اصلا به اشتباه وارد شده و می خواهیم ویرایش کنیم
با تشکر
ممنون که وقت میزارید.

mehdi.mousavi
شنبه 17 خرداد 1393, 07:12 صبح
خیلی ممنون از پاسختون یک سوال دیگر کدامیک از این حالات بهتره؟ انتخاب فیلد های یک جدول به عنوان کلید اصلی؟ یا اینکه برای هر جدولی یک فیلد id به عنوان کلید اصلی انتخاب کنیم که خاصیت auto incriment هم داره که در این صورت مارو از اپدیت کلید اصلی بی نیاز میکنه چون واقعا بعضی مواقع اپدیت کلید اصلی نیازه مثلا یک فرد با کد کارمندی که کد کارمندی اون کلید هست اگر بخواییم کد کارمندی رو تغییر بدیم لازم میشه یا اصلا به اشتباه وارد شده و می خواهیم ویرایش کنیم
با تشکر ممنون که وقت میزارید.


سلام.
کاملا درسته. در برخی اوقات، به روز کردن کلید اصلی (مثل شماره کارمندی، شماره تامین اجتماعی در برخی از کشور ها و ...) اجتناب ناپذیره به همین منظور هم بود که در پست اول، سوال شما رو با "بهتره ازش پرهیز کنیم" پاسخ دادم. نمیشه گفت استفاده از "شماره کارمندی" بعنوان کلید اصلی جدول بهتر (یا بدتر) از انتخاب یک Identity است. این انتخاب، خوبی ها و بدی های خودش رو داره. من، به شخصه، (با توجه به Transaction Log ها، Lock ها، Partitioning و ...) استفاده از یک Identity رو پیشنهاد می کنم.

موفق باشید.

سیدسبحان
دوشنبه 26 خرداد 1393, 16:34 عصر
ببخشید منم همین مشکل رو پیدا کردم (البته با کمی تفاوت)

ببینید من از یه کتاب دارم تمرین میکنم. طبق گفته اون(که درست هم هست) اگه اسم متغیر رو بزاریم ID، خودش به طور پیش فرض به عنوان کلید اصلی جدول میشناستش؛درست؟

خب من اجرا کردم و جدولم هم ساخته شدو اطلاعاتی واردش کردم.
کتاب میگه اسمشو تغییر بده (مثلا بزار Test) ، ولی با این تفاوت که قبل دستور، عبارت : [Key] رو بگذار که کار کنه.
اون از ویژوال 2012 استفاده کرده و میگه درسته. مال منم 2013.
من همین تغییرات رو دادم ولی ارور میده.
آیا این دستور(منظورم [Key] هست) ، کار نمیکنه؟
یعنی منم مجبور که یه پروسیجر بسازم؟

mehdi.mousavi
سه شنبه 27 خرداد 1393, 15:37 عصر
ببخشید منم همین مشکل رو پیدا کردم (البته با کمی تفاوت) ببینید من از یه کتاب دارم تمرین میکنم. طبق گفته اون(که درست هم هست) اگه اسم متغیر رو بزاریم ID، خودش به طور پیش فرض به عنوان کلید اصلی جدول میشناستش؛درست؟ خب من اجرا کردم و جدولم هم ساخته شدو اطلاعاتی واردش کردم. کتاب میگه اسمشو تغییر بده (مثلا بزار Test) ، ولی با این تفاوت که قبل دستور، عبارت : [Key] رو بگذار که کار کنه. اون از ویژوال 2012 استفاده کرده و میگه درسته. مال منم 2013. من همین تغییرات رو دادم ولی ارور میده. آیا این دستور(منظورم [Key] هست) ، کار نمیکنه؟ یعنی منم مجبور که یه پروسیجر بسازم؟

سلام.
لطفا بفرمایید با چه خطایی مواجه شده اید و پیام خطا رو بصورت کامل اینجا قرار بدید تا دلیلش رو خدمتتون عرض کنم. سوال شما، ارتباطی با موضوع این تاپیک نداره و سناریوی کاملا مجزایی هستش. به بیان دیگه، خیر. شما باید بتونید از Key Attribute (همونطوریکه کتاب ذکر کرده) در VS2013 نیز استفاده کنید. بصورت پیش فرض، Entity Framework بر اساس Convention های موجود رفتار می کنه. یکی از این Convention ها، استفاده از Id یا نام کلاس + Id هستش که باعث میشه Property ی مورد نظر، کلید اون Entity در نظر گرفته بشه. وقتی EF نتونه کلید رو بر اساس این Convention پیدا کنه، اونوقت شما می تونید با Configuration اون Property رو صریحا کلید Entity معرفی کنید. برای این کار نیز از Key Attribute (یا Fluent API ها، اگر قصد ندارید در Entity Class خودتون دست ببرید) می تونید استفاده کنید.

موفق باشید.

سیدسبحان
سه شنبه 27 خرداد 1393, 21:21 عصر
سلام.
لطفا بفرمایید با چه خطایی مواجه شده اید و پیام خطا رو بصورت کامل اینجا قرار بدید تا دلیلش رو خدمتتون عرض کنم. سوال شما، ارتباطی با موضوع این تاپیک نداره و سناریوی کاملا مجزایی هستش. به بیان دیگه، خیر. شما باید بتونید از Key Attribute (همونطوریکه کتاب ذکر کرده) در VS2013 نیز استفاده کنید. بصورت پیش فرض، Entity Framework بر اساس Convention های موجود رفتار می کنه. یکی از این Convention ها، استفاده از Id یا نام کلاس + Id هستش که باعث میشه Property ی مورد نظر، کلید اون Entity در نظر گرفته بشه. وقتی EF نتونه کلید رو بر اساس این Convention پیدا کنه، اونوقت شما می تونید با Configuration اون Property رو صریحا کلید Entity معرفی کنید. برای این کار نیز از Key Attribute (یا Fluent API ها، اگر قصد ندارید در Entity Class خودتون دست ببرید) می تونید استفاده کنید.

موفق باشید.


حالا مشکلم اینه:


من میخام اسم فیلدی که به عنوان کلید اصلی هست رو عوض کنم.
قبلا اسمش ID بود و جدولم ساخته شده. الان میخام بزارمش Test. توی کتاب گفته قبل از خط دستورت، عبارت [Key] رو بزاری کار میکنه. یعنی اینطوری :



[Key] public int Test { get; set; }


ولی برای من کار نکرد.
متدای دیگه شم کار نمیکنه. مثلا :



[MaxLength(20)]


مثل:



[MaxLength(20)] public string Title { get; set; }
که حد اکثر تعداد حروف رو تعیین میکنه و


یا



[Required]


مثل:

[Required] public string BloggerName { get; set; }


که میگه نباید فیلدمون null باشه.

اینم اروری که برای همه این متدهاش میده:


An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
Additional information: The model backing the 'Context' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

mehdi.mousavi
چهارشنبه 28 خرداد 1393, 07:05 صبح
اینم اروری که برای همه این متدهاش میده

سلام.
خطای مورد نظر ارتباطی به Data Annotation ها نداره. این خطا داره بهتون میگه که Model پس از ایجاد بانک، تغییر کرده. یعنی چی؟ یعنی فرضا در بار اول BloggerName رو Required تعریف نکرده بودید؛ در نتیجه، این فیلد در بانک Nullable تعریف شده. حالا دارید این فیلد رو در کلاس Required تعریف می کنید، یعنی دارید Schema ی جدول رو تغییر میدید. از اونجاییکه EF نمیخواد بطور خودکار Database شما رو حذف کنه و یک بار دیگه بر اساس تغییرات اعمال شده در کد Database رو ایجاد کنه، شما این پیام خطا رو میگیرید. برای حل اون، روش های متفاوتی وجود داره. یکی از این روش ها، این هستش که بصورت دستی Database رو پاک کنید تا در اجرای بعدی، بانک از نو ایجاد بشه. اما ممکنه Row هایی داشته باشید که بخواهید در بانک باقی بمونه، یا مایل باشید تا با هر بار ایجاد Database یکسری Row ی خاص در جداول مورد نظرتون بطور خودکار ثبت بشه، گویی که بانک حذف و مجددا ایجاد نشده و فقط Schema ی جداول تغییر کرده. برای اعمال چنین شراطی، باید با Code First Migration (http://msdn.microsoft.com/en-us/data/jj591621) و Migration Strategy های مختلف آشنا بشید...

موفق باشید.

سیدسبحان
چهارشنبه 28 خرداد 1393, 09:39 صبح
سلام.
خطای مورد نظر ارتباطی به Data Annotation ها نداره. این خطا داره بهتون میگه که Model پس از ایجاد بانک، تغییر کرده. یعنی چی؟ یعنی فرضا در بار اول BloggerName رو Required تعریف نکرده بودید؛ در نتیجه، این فیلد در بانک Nullable تعریف شده. حالا دارید این فیلد رو در کلاس Required تعریف می کنید، یعنی دارید Schema ی جدول رو تغییر میدید. از اونجاییکه EF نمیخواد بطور خودکار Database شما رو حذف کنه و یک بار دیگه بر اساس تغییرات اعمال شده در کد Database رو ایجاد کنه، شما این پیام خطا رو میگیرید. برای حل اون، روش های متفاوتی وجود داره. یکی از این روش ها، این هستش که بصورت دستی Database رو پاک کنید تا در اجرای بعدی، بانک از نو ایجاد بشه. اما ممکنه Row هایی داشته باشید که بخواهید در بانک باقی بمونه، یا مایل باشید تا با هر بار ایجاد Database یکسری Row ی خاص در جداول مورد نظرتون بطور خودکار ثبت بشه، گویی که بانک حذف و مجددا ایجاد نشده و فقط Schema ی جداول تغییر کرده. برای اعمال چنین شراطی، باید با Code First Migration (http://msdn.microsoft.com/en-us/data/jj591621) و Migration Strategy های مختلف آشنا بشید...

موفق باشید.

سلام.
عجب جوابی!
واقعا ممنون.
کاشکی همون اول میومدم از شما میپرسیدم.
ولی یه مشکلی هست، من انگلیسیم اصلا خوب نیست.:گریه:

میشه یه چیزی بگید که دست خالی نباشیم؟!!!:خجالت:
مثلا حذف دستی. آخه نمیدونم بانک کجاست!