ورود

View Full Version : جلوگیری از ثبت کلید خارجی نامعتبر در جدول هنگام ثبت به وسیله bulkinsert



moferferi
چهارشنبه 07 مرداد 1394, 21:25 عصر
سلام
میخواستم سوالم را توی بخش مربوط به asp.net بپرسم ولی گفتن شاید بیشتر مربوط به sql باشه
من واسه درج تعداد زیاد رکورد در entityframework از bulkinsert (http://www.dotnettips.info/post/1738/bulkinsert-%D8%AF%D8%B1-ef-codefirst)استفاده میکنم

اما مشکل اینه که بر فرض اگه دو جدول داشته باشیم که دارای کلید اصلی و کلید خارجی باشه.حتی اگه توی جدول کلید اصلی یک رکورد هم وجود نداشته باشه ، میشه توی جدول دوم رکورد با کلید خارجی نامعبر وارد کرد.
آیا این باگ مربوط به bulkinsert هست و یا اینکه در طراحی جدول مشکلی هست.؟

با تشکر

pbm_soy
پنج شنبه 08 مرداد 1394, 02:04 صبح
میتوانید در زمان ارتباط دادن دو جدول این امکان را بدهید که یک رکرود با کلید خارجی نامعتبر ثبت نگردد البته این مورد بصورت پیش فرض فعال میباشد گزینه Foreign key Constraint اگر درست یادم مانده باشد!
البته من نتونستم bulkinsert را ببینم ولی اگر کدش در دسترس باشد میتوانید آنرا ویرایش کنید وقبل از هر درج رکورد بررسی کنید شرایط برقرار است یاخیر

moferferi
پنج شنبه 08 مرداد 1394, 08:39 صبح
ریلیشن را از طریق خود sql بین دو تا جدول ایجاد کردم
List<Message> Lst = new List<Message>();
for (int i = 0; i < 100; i++)
{
Lst.Add(new Message
{
MemberID = 1,
Title = "a",
TextBody = "3",DateCreate="111111"
});
IheariCrmEntities db = new IheariCrmEntities();
db.BulkInsert(Lst);
db.SaveChanges();


در اینجا شما به جای مقدار MemberID هر عددی هم که بخواین میتونید بزارید و بدون هیچ خطایی ثبت میشه.این در حالیه که جدول member اصلا ردیفی داخلش نیست

pbm_soy
جمعه 09 مرداد 1394, 01:35 صبح
در خصوصیات relation چک کنید خاصیت Enforce Foreign key Constraint فعال است یا خیر؟ چون اگر فعال باشد قاعدتا نباید مشکلی داشته باشد!

در ضمن یک آزمایش دستی هم انجام بدید مثلا خودتان بصورت دستی در جدول دوم رکوردی تایپ کنید که memberID آن در جدول Member وجود نداشته باشدببینید چه اتفاقی میافتد؟
البته با وجود فعال بودن خاصیت مورد نظر بعید میدانم این اتفاق رخ دهد صرفا برای اینکه بفهمیم مشکل از کجاست؟ شاید هم bulkInsert این خاصیت را نادیده میگیرد

pbm_soy
جمعه 09 مرداد 1394, 01:46 صبح
من نتونستم لینک مربوط به BulkInsert که در پست اول دادید را ببینم ولی در لینک زیر گفته که بصورت پیش فرض constraint ها نادیده گرفته میشود

https://technet.microsoft.com/en-us/library/ms186247(v=sql.105).aspx

پس شما یا باید طبق چیزی که در این لینک گفته شده آرگومان CHECK_CONSTRAINTS را به آن بدهید و یا اینکه بذارید Insert ها بدون محدودیت انجام شود و پس از آن محتوای جدول را چک کنی با دستور زیر

alter table YourTable with check check constraint all

ژیار رحیمی
جمعه 09 مرداد 1394, 04:12 صبح
بله میشه در جدول دوم به جای کلید خارجی NULL بزار اینم به شرطی محقق خواهد شد که کلید خارجی در جدول دوم در طراحی جدول تیک Allow Nulls رو زده باشی و در ارتباط بین دو جدول همانطور دوست گرامی توضیح دادن
Enforce Foreign key Constraint فعال باشد.اگر در طراحی جدول تیک Allow Nulls برداشته شده باشه. حتما باید یه کلید خارجی اونم معتبر در حین درج رکورد در جدول دوم وارد شود.

moferferi
شنبه 10 مرداد 1394, 06:28 صبح
سلام
قضیه NULL فرق میکنه.وقتی ریلیشن برقرار باشه و خاصیت NULL فعال باشه میتونیم NULL درج کنیم.اما مقدار غیر معتبر را حتی وقتی میخوایم به صورت دستی توی تیبل مقداری وارد کنیم اجازه نمیده
احتمالا در BulkInsert به خاطر سرعت بالای درج دیتا این مورد را بررسی نمیکنه.

ژیار رحیمی
شنبه 10 مرداد 1394, 09:08 صبح
دوست گرامی یه شرح کاملی از این بخش از کارتون ارائه بدین .شاید یه روش کارامدتر با همفکری دوستان بیابیم.مثلا چرا و به چه دلیل میخوای حجم انبوهی رکورد رو یکباره اضافه کنی به دیتابیس
شما موقع گرفتن کد
MemberID یه چک نجام بده که در جدول مرجع وجود دارد یا نه اگر وجود نداشت پیغام بدی به کاربر.اگرم درحالت افزودن انبوه می خوای چک کنی میتونی اون کد های رو که وجود ندارد رکوردشو موقع افزودن نادیده بگیری

moferferi
دوشنبه 12 مرداد 1394, 19:58 عصر
بر فرض شما نیاز دارید که اطلاعات یک فایل اکسل را از طریق وب آپلود و محتوای اون را درون دیتابیس ذخیره کنید.ممکنه اون فایل حاوی هزار رکورد باشه.اگه قرار باشه واسه هر ردیف یک کوئری و درخواست سمت سرور بره که فاجعه به بار میاد.

در حال حاضر برای سازمانی قرار شده یک اتوماسیون ساده طراحی کنم(هر چند که پیشنهاد دادم از microsoft xchange استفاده کنن)
روش کار در هنگام ارسال پیام اینه که شما ابتدا یک پیام ایجاد میکنید و در جدول دیگه به ازای هر گیرنده پیام یک ردیف شامل id پیام و id گیرنده درج میکنید.حال فرض کنید برای 200 نفر قراره پیام ارسال بشه.
در حالت معمولی اگه قرار باشه یک پروسیجر و یا متد saveChanges را صد بار صدا بزنیم ، این به معنی صد بار رفت و برگشت به دیتابیس تحمیل بار اضافی به سروره.
ولی در حالت معقول به روشی که توی پست بالا گفتم میشه ابتدا یک list حاوی همون تعداد رکورد را ایجاد کرد و سپس با یک کوئری و رفت و برگشت به سرور هر تعداد رکوردی که نیاز دارید را در دریتابیس ذخیره کنید.
البته فعلا به جای استفاده از روش bulkinsert از متد addrange استفاده کردم و پروژه را تحویل دادم.

moferferi
دوشنبه 12 مرداد 1394, 20:01 عصر
این هم لینک آموزش استفاده از bulinsert (http://www.dotnettips.info/post/1738/bulkinsert-%D8%AF%D8%B1-ef-codefirst)