PDA

View Full Version : سوال: مشکلات تغییر کدهای بسیار با ایجاد یک فیلد جدید در دیتابیس



hahaie
یک شنبه 29 مهر 1397, 08:49 صبح
دوستان سلام.
فرض کنید دو تا جدول داریم که یکی مشخصات افراد و دیگری ترددهای اونها رو ثبت میکنه.
طبق درخواست کاربر اونها فقط یک فرم نیاز داشتند که با توجه به حجم بالای ورود و خروج افراد رو در کمترین زمان ممکن ثبت کنن.
برای همین من بالای فرم یک جعبه متن برای کد ملی گذاشتم و موقع خروج از اون گفتم اگر کد ملی از قبل وجود داشت مشخصات اون رو توی چند تا تکست باکس زیرش نشون کاربر بده(چون شاید بخواهد ویرایش کند) و در ادامه بتونه توی تکست باکس های مربوط به جدول تردد،تردد اون رو ثبت کنه.
ولی اگر کد ملی از قبل وجود نداشت کاربر بتونه اول مشخصات فرد و بعد از اون اولین تردد اون رو با استفاده از چند تا تکست باکس ثبت بکنه.
یه گرید هم گذاشتم پایین فرم که جنبه نمایشی داره و ستون هاش از جوین دو جدول(کد ملی،نام و نام خانوادگی،تلفن،آدرس،نوع تردد(ورود یا خروج)،تاریخ و ساعت تردد و...) مذکور هستند.
و گفتم که هر بار کاربر روی رکوردهای گرید کلیک کرد اطلاعات سلول های اون رکورد رو به تکست باکس های بالای اون منتقل کنه.(با دستور انتساب).
و همون موقع کاربر میتونه اطلاعات فرد یا تردد اون رو با استفاده از دکمه های جداگانه و تکست باکس ها تغییر بده.
حالا سوال بنده اینه:کاربر از من خواسته چند تا فیلد برای مشخصات افراد اضافه کنم:
1.با توجه به اینکه با کلیک روی هر رکورد اطلاعات ستون ها(با استفاده از شماره ستون)رو به تکست باکس ها منتقل میکنه تغییر شماره ستون ها توی همه کدها کار رو برای رکورد جدید یا ویرایش رکورد سخت میکنه.
2.اصلا این روش درست هستش که با دستور انتساب اطلاعات سلولهای هر رکورد گرید رو به تکست باکس منتقل میکنم؟یا روش مناسبتری هست؟
نکته اینکه ستونهای گرید از جوین دو جدول هستند.
ممنون

ali_md110
یک شنبه 29 مهر 1397, 09:29 صبح
روش مناسب بکارگیری ORM ها مثل Entity framework و جنریک ها هست یعنی بجای اینکه از لیست هایی استفاده کنیم که با دستورات رشته ای و یا رشته ها به کنترها نسبت داده شده اند
از لیست های جنریک و عبارات Linq و لامبدا بهره ببریم تا به محض تغییرات در سمت مدلهای بانک اطلاعاتی تغییرات توسط کامپایلر بصورت هوشمند ردیابی و خطایابی شود
در ضمن میتونید بجای تکست باکس تغییرات را در همان گراید انجام بدید و نیازی نیست اطلاعات به تکست باکس منتقل کنید

hahaie
یک شنبه 29 مهر 1397, 12:58 عصر
ممنون
در مورد استفاده از لیست های جنریک و عبارات Linq میشه بیشتر توضیح بدین.من قبلا از Linq برا select استفاده میکردم و نحوه استفاده از اون رو برای دستورات DML مثل درج،بروزرسانی و یا حذف نمیدونم.
ضمن اینکه تا جایی که یادمه توی Linq هم اسم فیلدهایی رو که میخواستیم ذکر میکردیم و چه بسا ممکن باشه همه فیلدها رو نخوایم.
اگه توضیح بدین ممنون میشم.
اما مورد دوم:فرمودید که بجای تکس باکس از خود گرید استفاده کنم.توضیح بنده اینکه رکوردهای گرید حاصل جوین 2 جدول هستش بعد خود گرید چطوری میخواد بفهمه اطلاعات رو در کدوم جدول درج یا بروزرسانی کنه؟
ممنون

ali_md110
دوشنبه 30 مهر 1397, 08:05 صبح
وقتی دستور اسکیولی مینویسیم بدینصورت


SELECT Name Famil ....From Person

در بخش نمایشی برنامه برای نمایش داده در فیلدها اینجوری مینویسیم


txtPhone.text=DataRow["Phone"]


و اگر در تمام فرمهای برنامه کنترلها بدینصورت مقید شده باشد فرض کنیم دوست داریم فیلد Phone در قسمت بانک برنامه به Mobile تغییر نام دهیم باید در کل پروژه فیلدهای رشته ای "Phone" را پیدا کرد و تبدیل به Mobile کرد
حالا شما فکرش بکنید اگر تعداد زیادی فیلد نیاز به تغییر باشد اونوقت خیلی مشکل بوجود میاد و عملا در توسعه چنین پروژه ای با مشکل بر میخوریم
را چاره تحت کامپایلر قرار دادن تغییرات هست یکی از روشها بکارگیری ORM ها هست
در این روش بجای دستورات رشته ای از Property ها برای دسترسی به فیلدهای بانک بهره می بریم


txtPhone.text=dbcontext.Phone

در اینجا دیگر اثری از رشته نیست و اگر در سطح مدل برنامه فیلد Phone به Mobile تغییر پیدا کرد توسط ادیتور ویژوال استودیو و با ابزارهای جانبی مانند Resharper تغییرات بصورت داینامیک میتواند شود و خیلی کمتر نیاز به تغییر دستی عنوان این فیلدها هست

دستورات درج توسط ef خیلی سادست


dbcontext.Phone.Add(new Phone{id=1,name=3232})
dbcontext.savechanges()

دیگر خبری از دستورات sql نیست متد Add در پس زمینه تبدیل به دستورSQLشده و با savechanges به سمت دیتابیس ارسال میشود


برای بکارگیری گراید در درج اطلاعات به هیچ وجه نباید به فکر sql جوین شده افتاد
روش کار بدینصورت هست که فیلدهایی که نیاز هست اطلاعات اون در گرید نشون داده بشه ابتدا مشخص میسازیم
مثلا :جدول Person شامل فیلدهایی مثل FirstName, LastName
و جدول Details شامل فیلدهایی مثل Tel, Address
برای اینکار یک کلاس بنام People میسازیم


public calss Peapole
{
public string FirstName{get;set;}
public string LastName{get;set;}
public string Address{get;set;}
public string Tel{get;set;}


}


حالا باید لیستی را توسط EF از روی دو جدول Person و Detail بسازیم


var list=dbcontext.Detail.Select(x=> new Peapole{FirstNme=x.Person.FirstName,LastName=x.Per son.LastName,Tel=x.Tel,Address=x,Address}).Tolist( );


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


grid.datasource=list

و برای انتقال اطلاعات ویرایش شده از گزاید به بانک هم باید به تفکیک فیلد های هر جدول را از گرید استخراج و در بانک ذخیره کنیم

که زیاد سخت نیست

hahaie
سه شنبه 01 آبان 1397, 10:14 صبح
ali_md110 (http://barnamenevis.org/member.php?18325-ali_md110) عزیز بسیار ممنونم از وقتی که گذاشتین و راه رو نشون دادین.دکمه ای برا تشکر پیدا نکردم که ازش استفاده کنم.خیلی ممنونم
فقط نمیدونم نمونه برنامه ای برا این چیزایی که شما گفتین هست یا نه(نمیدونم با تکنولوژی چی سرچ کنم) چون اگه بشینم بررسیش کنم فک کنم راحت تر بتونم ادامه بدم.
ممنونم میشم اگه زحمتی نیست لینکی چیزی در این مورد که نمونه برنامه ای با سورس باشه بهم بدین

ali_md110
سه شنبه 01 آبان 1397, 12:37 عصر
خواهش میکنم هدف کمک به همدیگه هست
آموزش های ef code first را در سایت جناب نصیری پیگیری کنید سایت ارزشمندی هست تمام مباحث حرفه ای میتونید اینجا مطالعه کنید
مباحث MVVM با WPF و Dependeny injectionو AOP -جنریکها را در لینک زیر پیگیری کنید

https://www.dotnettips.info/post/831/ef-code-first-1 (https://www.dotnettips.info/post/831/ef-code-first-1)

hahaie
سه شنبه 01 آبان 1397, 13:46 عصر
دوست عزیز ابتدای بحث از ASP MVC صحبت شده حوزه کاری بنده C# هستشا!
و اینکه سایت جناب نصیری لینکشو دارین؟

ali_md110
سه شنبه 01 آبان 1397, 15:58 عصر
لینکی که توی پست قبلی فرستادم سایت آقای نصیری هست
در ضمن در لینک فوق ef code first را بر مبنای #cتوضیح داده و فرقی نمی کند حوزه ی کاری شما MVC باشد یا windows desktop
نحوه استفاده ef در هر دو پلتفرم وب و ویندوز شبیه هم هستند و باید از کلاسهای #c بهره ببرید
مهم درک شما از مکانیزم این تکنیک هست
موفق باشید

hahaie
یک شنبه 20 آبان 1397, 13:57 عصر
سلام
بچه ها من نتونستم یه نمونه برنامه به روشی که گفتین پیدا کنم
چند نمونه که با ASP کار شده بود پیدا کردم ولی C# میخوام.
شما نمونه ای سراغ ندارین؟

mr.sirwan
سه شنبه 06 آذر 1397, 21:23 عصر
بنده قبلا یه برنامه خیلی ساده و صرفا جهت تست و در دوران یادگیری EF CodeFirst نوشته بودم که تنها کارش ذخیره کشور و استان و شهرها توی دیتابیسه. تا حد امکان کامنت گذاری هم کردم، امیدوارم به کارتون بیاد

http://s8.picofile.com/file/8344056834/EntityFramework_06.rar.html

رامین مرادی
چهارشنبه 07 آذر 1397, 12:36 عصر
بنده قبلا یه برنامه خیلی ساده و صرفا جهت تست و در دوران یادگیری EF CodeFirst نوشته بودم که تنها کارش ذخیره کشور و استان و شهرها توی دیتابیسه. تا حد امکان کامنت گذاری هم کردم، امیدوارم به کارتون بیاد

http://s8.picofile.com/file/8344056834/EntityFramework_06.rar.html

خودم کلا با ado.net کار میکنم. به این کد فرست هم تازگیا علاقه پیدا کردم. فقط یه مشکلی که دارم اینه که اون قسمت تغییر ساختار جداول و پاک شدن داده های قبلی رو متوجه نمیشم.

mr.sirwan
چهارشنبه 07 آذر 1397, 14:12 عصر
ببینین فرض کنین توی کلاس city یه پراپرتی دیگه به اسم AddedDate که تاریخ ثبت شهر رو نگهداری میکنه به کلاس اضافه کنیم، خب این یعنی تغییر در ساختار مدل و این تغییر شامل هر چیز دیگه ای مثل تغییر نام یک پراپرتی یا حذف و اضافه کردن پراپرتی به کلاسهامون میشه، پس توی اون سناریویی که من استفاده کردم وقتی EF داره میبینه که مدل پروژه ما نسبت به دیتابیس قبلی که ساخته شده تغییر کرده، میره کل دیتابیس رو حذف میکنه و با ساختار جدید یه دیتابیس جدید ایجاد میکنه و در ادامه باید بگم که EF تنها با این سناریو کار نمیکنه بلکه خودمون انتخاب میکنیم که از کدوم سناریو استفاده کنیم.

توی EF-CodeFirst چهار تا سناریو داریم:
1. اگر دیتابیس موجود نباشه، EF میاد دیتابیس رو میسازه:
Database.SetInitializer(new CreateDatabaseIfNotExists<DatabaseContext>());

2. در هر بار اجرای برنامه دیتابیس حذف و دوباره ساخته میشه:
Database.SetInitializer(new DropCreateDatabaseAlways<DatabaseContext>());

3. اگر مدل پروژه ما تغییر پیدا کرد، دیتابیس حذف و طبق آخرین تغییرات مدل، یه دیتابیس جدید ساخته میشه:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DatabaseContext>());

چهارمین و پرطرفدارترین سناریو که به اسم migrations معروفه بدون اینکه دیتابیس رو حذف کنه، آخرین تغییرات مدل رو روی دیتابیس با دقت بسیار زیادی اعمال میکنه:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DatabaseContext, Migrations.Configuration>());
سه تا سناریوی اول بصورت پیشفرض وجود دارن و میتونین استفاده کنین، اما برای سناریوی چهارم یعنی همون migrations باید از طریق package manager console و توسط دستور Enable-Migrations -Project Models این سناریو رو براش فعال کنین

رامین مرادی
چهارشنبه 07 آذر 1397, 14:18 عصر
ببینین فرض کنین توی کلاس city یه پراپرتی دیگه به اسم AddedDate که تاریخ ثبت شهر رو نگهداری میکنه به کلاس اضافه کنیم، خب این یعنی تغییر در ساختار مدل و این تغییر شامل هر چیز دیگه ای مثل تغییر نام یک پراپرتی یا حذف و اضافه کردن پراپرتی به کلاسهامون میشه، پس توی اون سناریویی که من استفاده کردم وقتی EF داره میبینه که مدل پروژه ما نسبت به دیتابیس قبلی که ساخته شده تغییر کرده، میره کل دیتابیس رو حذف میکنه و با ساختار جدید یه دیتابیس جدید ایجاد میکنه و در ادامه باید بگم که EF تنها با این سناریو کار نمیکنه بلکه خودمون انتخاب میکنیم که از کدوم سناریو استفاده کنیم.

توی EF-CodeFirst چهار تا سناریو داریم:
1. اگر دیتابیس موجود نباشه، EF میاد دیتابیس رو میسازه:
Database.SetInitializer(new CreateDatabaseIfNotExists<DatabaseContext>());

2. در هر بار اجرای برنامه دیتابیس حذف و دوباره ساخته میشه:
Database.SetInitializer(new DropCreateDatabaseAlways<DatabaseContext>());

3. اگر مدل پروژه ما تغییر پیدا کرد، دیتابیس حذف و طبق آخرین تغییرات مدل، یه دیتابیس جدید ساخته میشه:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DatabaseContext>());

چهارمین و پرطرفدارترین سناریو که به اسم migrations معروفه بدون اینکه دیتابیس رو حذف کنه، آخرین تغییرات مدل رو روی دیتابیس با دقت بسیار زیادی اعمال میکنه:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DatabaseContext, Migrations.Configuration>());



بطبع چهارمین مورد خیلی کاربردیه. اون مایگریشن (اگه درست نوشته باشم) باید بهش بگیم چه کار بکنه یا یه سری کلاس آماده هست؟

mr.sirwan
چهارشنبه 07 آذر 1397, 14:27 عصر
بطبع چهارمین مورد خیلی کاربردیه. اون مایگریشن (اگه درست نوشته باشم) باید بهش بگیم چه کار بکنه یا یه سری کلاس آماده هست؟

سه تا سناریوی اول بصورت پیشفرض وجود دارن و میتونین استفاده کنین، اما برای سناریوی چهارم یعنی همون migrations باید از طریق package manager console و توسط دستور Enable-Migrations -Project Models این سناریو رو براش فعال کنین، با اینکار یه پوشه migrations توی پروژه مدل ایجاد میشه که داخلش یه کلاس configurations هست و میتونین کانفیگ ها و داده های اولیه تون رو اونجا بنویسین، این کلاس رو بصورت دستی و بدون نیاز به اون دستوری که گفتم هم خودتون میتونین بسازین

رامین مرادی
پنج شنبه 08 آذر 1397, 08:35 صبح
سه تا سناریوی اول بصورت پیشفرض وجود دارن و میتونین استفاده کنین، اما برای سناریوی چهارم یعنی همون migrations باید از طریق package manager console و توسط دستور Enable-Migrations -Project Models این سناریو رو براش فعال کنین، با اینکار یه پوشه migrations توی پروژه مدل ایجاد میشه که داخلش یه کلاس configurations هست و میتونین کانفیگ ها و داده های اولیه تون رو اونجا بنویسین، این کلاس رو بصورت دستی و بدون نیاز به اون دستوری که گفتم هم خودتون میتونین بسازین

تشکر:تشویق::قلب: