PDA

View Full Version : حرفه ای: ثبت بیش از 1000 رکورد در ثانیه توسط EF



abasfar
شنبه 22 خرداد 1395, 12:50 عصر
سلام
دوستان من حدود 1000 رکورد در ثانیه ورودی دارم که از نوع رشته هستش و به صورت تک تک برام ارسال میشه و باید تو دیتا بیس ذخیره کتنم چون می دونم تعدا زیاد کانکشن باید باز و بسته شه و این فشار زیادی به دیتابیس میاره به نظر شما از چه متدهایی استفاده کنم

hi level hdd
شنبه 22 خرداد 1395, 13:32 عصر
یکی از راه ها این هست، اول داده هاتونو توی یک لیست درج کنید و هر زمان به تعداد دلخواه رسید در بانک درج کنید.

abasfar
شنبه 22 خرداد 1395, 14:20 عصر
اطمینان این کار خیلی کمه
شما در نظر بگیرید استثنا رخ بده یا سیستم خاموش بشه یا تو یک زمان خاص این لیست پر نشه و ...
فکر کنم یک راه صد در صد تظمینی داشته باشیم

mrprestige
شنبه 22 خرداد 1395, 18:34 عصر
سلام
دوستان من حدود 1000 رکورد در ثانیه ورودی دارم که از نوع رشته هستش و به صورت تک تک برام ارسال میشه و باید تو دیتا بیس ذخیره کتنم چون می دونم تعدا زیاد کانکشن باید باز و بسته شه و این فشار زیادی به دیتابیس میاره به نظر شما از چه متدهایی استفاده کنم
سلام دوست من یه Nuget (https://efbulkinsert.codeplex.com/) برات گیر آوردم فکر کردم شاید بدردت بخوره .

abasfar
یک شنبه 23 خرداد 1395, 09:20 صبح
سلام دوست من یه Nuget (https://efbulkinsert.codeplex.com/) برات گیر آوردم فکر کردم شاید بدردت بخوره .
سلام
ممنونم از لطفتان فقط این روش هم دقیقا مثل روش دوست عزیزمان
hi level hdd هستش
چون من تک تک داده را می خوانم باید توو این روشی که شما فرمودین لیست کنم و ان لیست را درج کنم که مشکلات خودش را داره

hamid_hr
یک شنبه 23 خرداد 1395, 10:21 صبح
خب اگه یه کانکشن بسازی و فقط با همون کانکشن همه اطلاعاتو درج کنی چی میشه؟
اینطوری نمیخواد هزار بار کانکت بشی و دیس کانکت بشی

radeon
یک شنبه 23 خرداد 1395, 11:40 صبح
سلام

چیزی در مورد TVP (Table Valued Parameters) شنیدید؟ ممکنه به دردتون بخوره

http://www.c-sharpcorner.com/UploadFile/78607b/using-table-valued-parameters-in-entity-framework/

abasfar
یک شنبه 23 خرداد 1395, 14:18 عصر
خب اگه یه کانکشن بسازی و فقط با همون کانکشن همه اطلاعاتو درج کنی چی میشه؟
اینطوری نمیخواد هزار بار کانکت بشی و دیس کانکت بشی
خوب اگه در نظر بگیریم من هر داده ای را که میاد همراه با DbContext اصلی به یک ترید بدم خطا به وجود نمیاد ؟!؟
(تو یک ترید در حال save و تو ان یکی add و مشکلاتی همچون Time Out , .....)

abasfar
یک شنبه 23 خرداد 1395, 14:19 عصر
سلام

چیزی در مورد TVP (Table Valued Parameters) شنیدید؟ ممکنه به دردتون بخوره

http://www.c-sharpcorner.com/UploadFile/78607b/using-table-valued-parameters-in-entity-framework/

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

radeon
یک شنبه 23 خرداد 1395, 14:47 عصر
اخب این روش چطوره به نظرتون: داده هایی که تک تک دریافت میکنید داخل یک فایل ذخیره کنیم، خط به خط
اون فایل رو به صورت دوره ای چک کنیم
هربار اطلاعات وارد شده رو به دیتابیس انتقال بدیم
و محتوای فایل رو پاک کنیم
و همین لوپ ادامه داشته باشه....

اینطوری وقتی داده جدیدی نیومده باشه کانکشنی برقرار نمیشه

kamiloted
یک شنبه 23 خرداد 1395, 16:17 عصر
سلام
دوستان من حدود 1000 رکورد در ثانیه ورودی دارم که از نوع رشته هستش و به صورت تک تک برام ارسال میشه و باید تو دیتا بیس ذخیره کتنم چون می دونم تعدا زیاد کانکشن باید باز و بسته شه و این فشار زیادی به دیتابیس میاره به نظر شما از چه متدهایی استفاده کنم

سلام دوست عزیز، به نظرم کار زیاد سختی نیست.
فقط بفرمایید این ورودی ها چی هستند.آیا مجزا از همند.آیا مرتبطند به هم.
گروه بندی شده هست. از چی میخواید بگیرید این 1000 رکورد رو؟
و آیا همه این هزارتا را در یک رکورد از جدول میخواید ذخیره کنید یا...؟؟

abasfar
یک شنبه 23 خرداد 1395, 16:42 عصر
اخب این روش چطوره به نظرتون: داده هایی که تک تک دریافت میکنید داخل یک فایل ذخیره کنیم، خط به خط
اون فایل رو به صورت دوره ای چک کنیم
هربار اطلاعات وارد شده رو به دیتابیس انتقال بدیم
و محتوای فایل رو پاک کنیم
و همین لوپ ادامه داشته باشه....

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

abasfar
یک شنبه 23 خرداد 1395, 16:45 عصر
سلام دوست عزیز، به نظرم کار زیاد سختی نیست.
فقط بفرمایید این ورودی ها چی هستند.آیا مجزا از همند.آیا مرتبطند به هم.
گروه بندی شده هست. از چی میخواید بگیرید این 1000 رکورد رو؟
و آیا همه این هزارتا را در یک رکورد از جدول میخواید ذخیره کنید یا...؟؟


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

kamiloted
یک شنبه 23 خرداد 1395, 16:59 عصر
سلام
همه داده ها یک رشته هستند که تو یک جدول درج میشند، فقط به صورت ارایه ای از رشته ها ارسال نمیشه بلکه تک به تک (یک رشته) ارسال میشه و قرار هست هر داده ای (رشته) که دریافت شد یک رکورد در جدول بشه
دوست عزیز آیا امکانش هست من پروژه شما رو با تیم ویوور و یا غیره ببینم؟

alireza_s_84
یک شنبه 23 خرداد 1395, 17:19 عصر
سلام
دوستان من حدود 1000 رکورد در ثانیه ورودی دارم که از نوع رشته هستش و به صورت تک تک برام ارسال میشه و باید تو دیتا بیس ذخیره کتنم چون می دونم تعدا زیاد کانکشن باید باز و بسته شه و این فشار زیادی به دیتابیس میاره به نظر شما از چه متدهایی استفاده کنم

اگر از sqlserver استفاده میکنید 1000 رکورد در ثانیه اصلا چیز قابل توجهی محسوب نمیشه.

davidrobert
یک شنبه 23 خرداد 1395, 22:31 عصر
دوست عزیز تکنولوژی EF تکنولوژی خیلی خوبه برای ارتباط با دیتابیس هستش ولی اگه پروژه شما سنگین هستش اصلا روش مناسبی رو انتخاب نکردید برای ارتباط با دیتابیس. چون در روش ای اف برنامه تک تک کلاس های ایجاد شده رو بررسی میکنه یعنی یه کار خیلی وقت گیری انجام میده و هرچقدر اطلاعات بیشتر بشه عفت ثبت و نمایش اطلاعات بیشتر میشه و سرعت برنامه به شدت پایین میاد.چون با ای اف کار میکردم این مشکل رو دیدم. ولی با تکنولوژی جدید ADO کار میکنم سرعت کار با دیتابیس من بیشتر و کد نویسی من کمتر شده.
این 2 تا سورس من ببین
http://sayyehban.blogfa.com/post/24
http://sayyehban.blogfa.com/post/55
این 2 تا سورس رو به وسیله استاد عزیز آقا یونس نوشتم به کارتون میاد سرعت کارتون بیشتر میشه در ADO

khosro_68
دوشنبه 24 خرداد 1395, 01:27 صبح
سلام
دوستان من حدود 1000 رکورد در ثانیه ورودی دارم که از نوع رشته هستش و به صورت تک تک برام ارسال میشه و باید تو دیتا بیس ذخیره کتنم چون می دونم تعدا زیاد کانکشن باید باز و بسته شه و این فشار زیادی به دیتابیس میاره به نظر شما از چه متدهایی استفاده کنم

اگه از sql server استفاده میکنی مشکلی پیش نمیاد من حجم بیشتر از اینم ثبت کردم

veniz2008
دوشنبه 24 خرداد 1395, 10:58 صبح
دوست عزیز تکنولوژی EF تکنولوژی خیلی خوبه برای ارتباط با دیتابیس هستش ولی اگه پروژه شما سنگین هستش اصلا روش مناسبی رو انتخاب نکردید برای ارتباط با دیتابیس. چون در روش ای اف برنامه تک تک کلاس های ایجاد شده رو بررسی میکنه یعنی یه کار خیلی وقت گیری انجام میده و هرچقدر اطلاعات بیشتر بشه عفت ثبت و نمایش اطلاعات بیشتر میشه و سرعت برنامه به شدت پایین میاد.چون با ای اف کار میکردم این مشکل رو دیدم. ولی با تکنولوژی جدید ADO کار میکنم سرعت کار با دیتابیس من بیشتر و کد نویسی من کمتر شده.
این 2 تا سورس من ببین
http://sayyehban.blogfa.com/post/24
http://sayyehban.blogfa.com/post/55
این 2 تا سورس رو به وسیله استاد عزیز آقا یونس نوشتم به کارتون میاد سرعت کارتون بیشتر میشه در ADO
سلام.
اینکه مشکل پروژه شما چی بوده که باعث افت سرعت شده رو من نمیدونم ولی با قاطعیت بهتون میگم که مشکل از Entity Framework نیست. باید دید تو Entity Framework چطور برنامه نویسی کردید. توی هر تکنولوژی اگه بصورت صحیح از امکانات استفاده نشه خروجی مطلوب حاصل نمیشه. اینکه علت مشکل رو پیدا نکنیم و به تکنولوژی ADO برگردیم فقط پاک کردن صورت مساله هستش.
الان دیگه هیچ پروژه بزرگی (حتی هیچ پروژه کوچیک) که قرار باشه استفاده تجاری بشه رو با ADO نمی نویسن (شاید فقط در یک حالت اونم نداشتن دانش کافی سمت ENtity Framework باشه!).
سرعت بالا مقوله ای نیست که بگیم اگه از Entity استفاده بشه دیگه همه چی Ok هستش. باید همه اصول بالا رفتن سرعت مثل گذاشتن ایندکس مناسب، بررسی Execution Plan های تولیدی توسط SQL، استفاده صحیح از متدهای آماده در LINQ و ... رو در نظر گرفت. فقط مطمئن باشید که مشکل از Entity Framework نبوده چون من الان خودم توی پروژه های تجاری که بصورت تیمی کار می کنیم فقط از ENtity Framework استفاده می کنیم. منظور من از ENtity Framework فقط از نوع Code First هستش.

سلام
دوستان من حدود 1000 رکورد در ثانیه ورودی دارم که از نوع رشته هستش و به صورت تک تک برام ارسال میشه و باید تو دیتا بیس ذخیره کتنم چون می دونم تعدا زیاد کانکشن باید باز و بسته شه و این فشار زیادی به دیتابیس میاره به نظر شما از چه متدهایی استفاده کنم
داده های دریافتی رو می تونید در یک List قرار بدید و با استفاده از Bulk Insert اونها رو درج کنید. کاملا تفاوت سرعت رو لمس خواهید کرد. من یک sample کد براتون میذارم که می تونید بعد از اضافه کردن bulk insert به پروژتون ازش استفاده کنید. همین کد رو اگه بخواید با متدهای Add یا AddRange توی دیتابیس درج کنید تفاوت زمانی برای 1000 رکورد چیزی در حدود 14 ثانیه هست (توی یک سیستم با سخت افزار معمولی). بعبارتی با bulk insert در حد 3 ثانیه و در حالت هایی که از Add یا AddRange استفاده بشه حدود 17 ثانیه طول میکشه. نحوه استفاده از Bulk Insert هم بصورت زیر هستش :
در این روش ابتدا باید پکیج مربوط به BulkInsert را از طریق Nuget و با کد زیر بر روی پروژه نصب کنید ( اطلاعات بیشتر در وب سایت این شرکت https://efbulkinsert.codeplex.com/ قابل دریافت هستش) :
Install-Package EntityFramework.BulkInsert-ef6
حال در محلی که قصد استفاده از BulkInsert رو داریم فضای نام
using EntityFramework.BulkInsert.Extensions;
رو اضافه می کنیم. نحوه استفاده هم به شکل زیر هست که من یک لیست 1000 تایی رو بهش پاس دادم.

using (DataBaseContext context = new DataBaseContext())
{
List<Category> catlist = new List<Category>();
for (int i = 0; i < 1000; i++)
{
catlist.Add(new Category { CategoryName = "cat" + i.ToString() });
}
context.BulkInsert(catlist);
context.SaveChanges();
MessageBox.Show("Added");
}

موفق باشید.

abasfar
جمعه 28 خرداد 1395, 10:37 صبح
اگر از sqlserver استفاده میکنید 1000 رکورد در ثانیه اصلا چیز قابل توجهی محسوب نمیشه.

وقتی داده ها تک به تک ارسال میشه و امکان استفاده از لیست نیست تا یکجا درج بشه سرعت پایین میاد

abasfar
جمعه 28 خرداد 1395, 10:40 صبح
دوست عزیز تکنولوژی EF تکنولوژی خیلی خوبه برای ارتباط با دیتابیس هستش ولی اگه پروژه شما سنگین هستش اصلا روش مناسبی رو انتخاب نکردید برای ارتباط با دیتابیس. چون در روش ای اف برنامه تک تک کلاس های ایجاد شده رو بررسی میکنه یعنی یه کار خیلی وقت گیری انجام میده و هرچقدر اطلاعات بیشتر بشه عفت ثبت و نمایش اطلاعات بیشتر میشه و سرعت برنامه به شدت پایین میاد.چون با ای اف کار میکردم این مشکل رو دیدم. ولی با تکنولوژی جدید ADO کار میکنم سرعت کار با دیتابیس من بیشتر و کد نویسی من کمتر شده.
این 2 تا سورس من ببین
http://sayyehban.blogfa.com/post/24
http://sayyehban.blogfa.com/post/55
این 2 تا سورس رو به وسیله استاد عزیز آقا یونس نوشتم به کارتون میاد سرعت کارتون بیشتر میشه در ADO

ممنونم
چون تکنولوژی EF انتخاب و تایید شده نمی توانیم سویچ کنیم
روش هایی بهینه سازی EF هست که با بستن وابستگی ها و AsNoTracking و... به خصوص در EF6 مشکلات سرعت و اجرا بهبود یافته

abasfar
جمعه 28 خرداد 1395, 10:42 صبح
اگه از sql server استفاده میکنی مشکلی پیش نمیاد من حجم بیشتر از اینم ثبت کردم

مشکلی تو sql server من هم ندارم مشکل در انتخاب متد برای بهبود عملکرد هستش و همچنین داشتن connection کمتر به دیتابیس

abasfar
جمعه 28 خرداد 1395, 10:47 صبح
سلام.
اینکه مشکل پروژه شما چی بوده که باعث افت سرعت شده رو من نمیدونم ولی با قاطعیت بهتون میگم که مشکل از Entity Framework نیست. باید دید تو Entity Framework چطور برنامه نویسی کردید. توی هر تکنولوژی اگه بصورت صحیح از امکانات استفاده نشه خروجی مطلوب حاصل نمیشه. اینکه علت مشکل رو پیدا نکنیم و به تکنولوژی ADO برگردیم فقط پاک کردن صورت مساله هستش.
الان دیگه هیچ پروژه بزرگی (حتی هیچ پروژه کوچیک) که قرار باشه استفاده تجاری بشه رو با ADO نمی نویسن (شاید فقط در یک حالت اونم نداشتن دانش کافی سمت ENtity Framework باشه!).
سرعت بالا مقوله ای نیست که بگیم اگه از Entity استفاده بشه دیگه همه چی Ok هستش. باید همه اصول بالا رفتن سرعت مثل گذاشتن ایندکس مناسب، بررسی Execution Plan های تولیدی توسط SQL، استفاده صحیح از متدهای آماده در LINQ و ... رو در نظر گرفت. فقط مطمئن باشید که مشکل از Entity Framework نبوده چون من الان خودم توی پروژه های تجاری که بصورت تیمی کار می کنیم فقط از ENtity Framework استفاده می کنیم. منظور من از ENtity Framework فقط از نوع Code First هستش.

داده های دریافتی رو می تونید در یک List قرار بدید و با استفاده از Bulk Insert اونها رو درج کنید. کاملا تفاوت سرعت رو لمس خواهید کرد. من یک sample کد براتون میذارم که می تونید بعد از اضافه کردن bulk insert به پروژتون ازش استفاده کنید. همین کد رو اگه بخواید با متدهای Add یا AddRange توی دیتابیس درج کنید تفاوت زمانی برای 1000 رکورد چیزی در حدود 14 ثانیه هست (توی یک سیستم با سخت افزار معمولی). بعبارتی با bulk insert در حد 3 ثانیه و در حالت هایی که از Add یا AddRange استفاده بشه حدود 17 ثانیه طول میکشه. نحوه استفاده از Bulk Insert هم بصورت زیر هستش :
در این روش ابتدا باید پکیج مربوط به BulkInsert را از طریق Nuget و با کد زیر بر روی پروژه نصب کنید ( اطلاعات بیشتر در وب سایت این شرکت https://efbulkinsert.codeplex.com/ قابل دریافت هستش) :
Install-Package EntityFramework.BulkInsert-ef6
حال در محلی که قصد استفاده از BulkInsert رو داریم فضای نام
using EntityFramework.BulkInsert.Extensions;
رو اضافه می کنیم. نحوه استفاده هم به شکل زیر هست که من یک لیست 1000 تایی رو بهش پاس دادم.

using (DataBaseContext context = new DataBaseContext())
{
List<Category> catlist = new List<Category>();
for (int i = 0; i < 1000; i++)
{
catlist.Add(new Category { CategoryName = "cat" + i.ToString() });
}
context.BulkInsert(catlist);
context.SaveChanges();
MessageBox.Show("Added");
}

موفق باشید.


ممنونم از توضیحاتتان
به پستهای قبلی هم نگاه کنید دوستان روش لیست را پیشنهاد داه بودن و من هم گفته بودم که این متد واسه من کارا نمی باشد چون اطلاعات دریافتی من حیاطی واسه نرم افزار و نباید از بین بره و خطایی داشته باشه و در ظمن در درج هر رکورد باید محاسباتی هم انجام بگیره که مشکلات را بیشتر میکنه


اما مشکل من که با اصل تعداد connection های بود را با متد UnitOfWork که واسه من خیلی هم کارا بود حل شد و فعلا مشکلی ندارم

unrealword
جمعه 28 خرداد 1395, 13:10 عصر
ممنونم از توضیحاتتان
به پستهای قبلی هم نگاه کنید دوستان روش لیست را پیشنهاد داه بودن و من هم گفته بودم که این متد واسه من کارا نمی باشد چون اطلاعات دریافتی من حیاطی واسه نرم افزار و نباید از بین بره و خطایی داشته باشه و در ظمن در درج هر رکورد باید محاسباتی هم انجام بگیره که مشکلات را بیشتر میکنه


اما مشکل من که با اصل تعداد connection های بود را با متد UnitOfWork که واسه من خیلی هم کارا بود حل شد و فعلا مشکلی ندارم


دوست عزیز می شه همین روش unitofwork برای منم بازش کنید

منم دقیقا همین مشکل رو دارم

abasfar
یک شنبه 30 خرداد 1395, 10:36 صبح
روش UnitOfWork دارای مزایا و معایبی هست و کاربردهای خاص خودش را داره پس حتما نمی توانید به این روش سویچ کنید مثلا در این روش از Repository استفاده کنید که بعد از insert کردن id برای شما برنمیگردونه یا ببه نظر من نباید از متد کلاس های مختلف تو یک UnitOfWork استفاده کنید
به هر حال این یک نمونه است

public class GenericRepository<TEntity> where TEntity : class
{
internal AppDbContext context;
internal DbSet<TEntity> dbSet;

public GenericRepository(AppDbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual void Insert(TEntity entity)
{
if (context.Database.Connection.State != System.Data.ConnectionState.Open)
{
context.Database.Connection.Open();
}
dbSet.Add(entity);
}
}


public class UnitOfWork : IDisposable
{
private readonly AppDbContext context;
public UnitOfWork()
{
context = new AppDbContext();
}

private GenericRepository<Book> bookRepository;

public GenericRepository<Book> BookRepository
{
get
{
if (this.appRepository == null)
{
this.bookRepository = new GenericRepository<Book>(context);
}
return bookRepository;
}
}
}

negar.rafie
دوشنبه 31 خرداد 1395, 15:44 عصر
:
Install-Package EntityFramework.BulkInsert-ef6
حال در محلی که قصد استفاده از BulkInsert رو داریم فضای نام
using EntityFramework.BulkInsert.Extensions;
رو اضافه می کنیم. نحوه استفاده هم به شکل زیر هست که من یک لیست 1000 تایی رو بهش پاس دادم.

using (DataBaseContext context = new DataBaseContext())
{
List<Category> catlist = new List<Category>();
for (int i = 0; i < 1000; i++)
{
catlist.Add(new Category { CategoryName = "cat" + i.ToString() });
}
context.BulkInsert(catlist);
context.SaveChanges();
MessageBox.Show("Added");
}

موفق باشید.

ممنون ولی من متوجه نشدم
فرض کنید ما ی جدول داریم با نام tblPerson با فیلد های زیر:
id که به صورت خودکار مقداردهی میشه و اتونامبر است
نام nvarchar(50)
فامیلی nvarchar(50)
سن int

حالا به چ صورت باید از این روش استفاده کنیم؟

negar.rafie
دوشنبه 31 خرداد 1395, 19:10 عصر
مشکل حل شد و تونستم استفاده کنم ولی ارور زیر را میده
the given key was not present in the dictionary entity framework

veniz2008
جمعه 04 تیر 1395, 16:49 عصر
مشکل حل شد و تونستم استفاده کنم ولی ارور زیر را میده
the given key was not present in the dictionary entity framework
فیلد identity رو هم باید مقدار بدی (هرچند در عمل بی تاثیر هست و خود sql مقدارش رو تولید میکنه) ولی شما باید یه مقدار الکی واسه فیلد identity بهش بدید.