من میخواهم عملکرد برنامه طوری باشد که برای هر کاربری که لاگین میکند یک کدی بر اساس مثلا نام شعبه ایجاد شود
و بر اساس آن کد وصل بشه به دیتابیس شعبه خودش
یعنی روی یک سرور بتوان چندین دیتابیس مختلف را هندل کرد
دیتابیس کاربران برای همه یکی باشد اما دیتابیس پروژه اصلی اختصاصی باشد، آیا در configurationPersistenceServises می تونم با گذاشتن if اینکار را بکنم؟ اگر بله خب چطور میتونم یک متغیر سراسری داشته باشم که مثلا در لایه UI مقداردهیش بکنم و تو لایه Persistence بتونم استفاده ش بکنم؟
با اجازه استاد
تا اونجایی که بنده میدونم شما وقتی میخوای DbContext رو کانفینگ کنی قبل از ران شدن اپلیکیشن اتفاق می افته و در حین اجرای برنامه شما نمیتونی یه ConnectionString جدید بهش بدی
مگه اینکه خودتون دستی نمونه سازی کنید. که با معماری در تناقضه
یعنی واقعا راهی نداره؟
این مورد خیلی ضروری هستش برام ...
من وقتی خودم دارم تریس میکنم، برنامه ران میشه اما در اولین دسترسی به دیتابیس میره سراغ این کلاس
بعید میدونم راهی نداشته باشه
شما حداقل اینو بهم بگید، من چجوری میتونم یک متغیر گلوبال در سطح سلوشن ایجاد بکنم؟ اگر بشه اینکار رو کرد براحتی با گذاشتن if میتونم بفرستم سراغ دیتابیس موردنظر خودم
اساتید گرامی خواهشا اگر در این گروه فعال هستید راهکار بدین، این موضوع مهمه و بدرد خیلی ها میخوره
شما که با بانک اطلاعاتی بانک کار می کنید بهتره با Dapper کار کنید سریع تره چون هم میتونه از StoredProcedure های SQL است و هم میتونه از دستورات مستقیم استفاده کنه و هم میتونه هر زمانی به راحتی با ConnectionString در لحظه نمونه سازی بشه. شما میتونید توی بانک اطلاعات کاربر رشته های اتصال هر شعبه رو قرار بدید و روی Claim هاش ذخیره کنید، تا هر وقت خواستید به بانک وصل بشید به رشته دسترسی داشته باشید.
فقط یه مقداری ریسکی هست ذخیره روی Claim ها. چون اگه رمز لو بره رشته اتصال هم لو میره. اگه روی بانک باشه و با هر کوئری بخواید رشته رو بگیرید سیستم کند میشه و اگه روی یه کلاس static ذخیره کنیم احتمال داره که سیستم سنگین بشه با کاربر های بیشتر.
یه دوره ای هم مربوط به Dapper روی سایت هست برای استاد مدائنی. حتما یه نگاهی بندازید
Dapper چیه دقیقا؟ من الان از sqlserver استفاده میکنم
پروژه رو نمیتونم الان ببرم روی یک پرووایدر دیگه ، کار خیلی پیچیده تر میشه اینطوری
سلام استفاده از چند دیتابیس در یک پروژه امکان پذیر است میتونی به این لینک مراجعه کنی:
https://code-maze.com/aspnetcore-multiple-databases-efcore/
این اون چیزی که من میخوام نیستش
این لینک رو قبلا مطالعه کرده بودم، فکر کنم این داره میگه بصورت همزمان بخوای چند دیتابیس رو تو یک پروژه بیاری ؛ با migrationAssembly میتونی اینکار رو بکنی
چیزی که شما میخوای اتصال در حین اجرای برنامه هست. شما باید یه کلاس Static درست کنید که توش یه دیکشنری از DbContext ها با رشته اتصال مختلف با کلید آی دی کاربر بسازید که با توجه به کاربر از اون کانتکس استفاده کنه
یا اینکه هر کاربر دارای یه پارامتری به عنوان آی دی شعبه داشته باشه که خود شعبه یه رشته اتصال خاص داشته باشه.
آی دی شعبه هم روی Claim های کاربر قرار بدید. هر وقت نیاز داشتید به کانتکس هم میتونید از اون کلاس با توجه به Claim کاربر کانتکس رو بگیرید.
این روش از نظر تئوری عملی هست ولی خیلی پردازش رو می بره بالا. تقریبا نابود میشه سیستم وقتی بخواید همچین کاری کنید.
پیشنهاد من استفاده از Dapper هست چون خیلی کمتر فشار میاره رو سرور و سبک تره.
باز اگه فرصت ندارید پروژه رو ببرید روی DB First و کار با Dapper رو یاد بگیرید مجبورید با همون روش بالا پیش برید.
حالا اگه تعداد شعبات کم باشه تا هفت هشت تا فشار خاصی نمیاد ولی بیشتر بشه سیستم خیلی تحت فشار قرار میگیره
مهندس ببخشید اما خیلی کلی و تئوری هست توضیحاتتون
اگر ممکنه یکم نمونه کد نشونم بدید ممنون میشم
اینی که فرمودین رو میخوام پیاده سازی بکنم:
"شما باید یه کلاس Static درست کنید که توش یه دیکشنری از DbContext ها با رشته اتصال مختلف با کلید آی دی کاربر بسازید که با توجه به کاربر از اون کانتکس استفاده کنه"
استفاده از claim کاربر که فکر نمیکنم بشه چونکه کاربر هنوز لاگین نکرده که بخوام از claimش تشخیص بدم مربوط به کدوم دیتابیسه
راستش متوجه نمیشم چرا پردازش میره بالا!!!!؟؟؟؟ چکار میخواد بکنه؟ فقط یک if رو بررسی میکنه و بر اساس اون addcontext انجام میده و تمام
هر دفعه نمونه سازی و اتصال به بانک از طریق ef زمان زیادی می بره.
کاربری هم که لاگین نکرده که معلوم نیست با کدوم شعبه کار داره؟
مگه سایتی که شما می نویسید سامانه نیست؟
خب تا قبل از لاگین سرویس خاصی نداره که
خب مهندس فقط همون یکبار اتصال و نمونه سازی اتفاق میافته، فقط کاری که باید انجام بشه اینه که نام بانک بر اساس یوزر انتخاب بشه ، بعد عملیات اتصال اتفاق بیافته
بله شما درست میفرمایید ابتدا کاربر لاگین میکنه بعد نام دیتابیسش باید مشخص بشه
ولی خب ببینید اجرایی کردن این کار پیچیدس برام میشه بیشتر توضیح بدین
ببینید الان در لایه persistense عملیات addDBContext انجام میشه، خب در این لایه من اصلا دسترسی به User.Identity.Name و یا سایر Claim ها هم ندارم! چطور تشخیص بدم کاربر کیه و اون کد مربوطه رو بخونم و بعدش چطور بگم این کد مربوط به این کانکشن استرینگ هست؟
کلا هر Request و Query که بخواد از بانک بخونه بهش DbContext رو بفرستید. تو همون لایه UI
مشکلم ارسالش نیست مشکلم اینه تو لایه persistense چطوری بگیرم؟ اونجا claim های یوزر یا هر چیز دیگری رو نمیشناسه!
اینجا:
سلام دوست عزیز وقت بخیر
دوست عزیز شما میتونی دیتابیس های مختلف رو داشته باشی و ConnectionStringرو در متد های مختلف عوض کنی ولی من چند وقت پیش اعلام کردم این روش منطقی نیست و بهتر هست استفاده نکنی و این مورد رو با استفاده از روابط و Relation ها پیاده سازی کنی
یعنی چی با استفاده از روابط و ریلیشن ها؟ میشه بیشتر توضیح بدین
ببینید این رو در پست های قبلی هم گفتم، من در حال حاضر در پروژه م دو تا دیتابیس دارم، یکی identity هستش که اطلاعات کاربران را نگهداری میکنه و یکی دیتابیس اصلی که دیتاهای مربوط به او شعبه رو نگهداری میکنه
کاری که میخوام بکنم اینه:
دیتابیس identity مشترک برای تمام شعبه ها باشه و به محض اینکه کاربر لاگین کرد برنامه با دیتابیس شعبه مربوط به اون کاربر کار بکنه
یعنی در واقع دیتابیس اصلی که مربوط به اطلاعات شعبه هستش رو نمیتونم مشترک بگیرم، اصلا مشتری اگر بفهمه قبول نمیکنه
یک پلن ساده این هستش که در جدول کاربران فیلدی اضافه بکنم برای نگهداری کد شعبه و به محض لاگین کردن کاربر، کد شعبه ش رو بخونم، بعد کانکشن استرینگ مربوط به اون شعبه را در DBContext باید add بکنم، تمام.
یعنی در واقع اگر تو این معماری نبودم و محدودیت لایه persistense رو نداشتم براحتی میتونم در یک پروژه asp net core معمولی با یک لایه این کار رو بکنم و با تعریف یک متغیر سراسری و خواندن مقدار فیلد کد شعبه conection String مربوطه را add بکنم
اما همونطور که قبلا هم عرض کردم گیرم انجام این کار در این معماری هستش، چون اگر مثلا من کد شعبه را با ورود کاربر بخونم نمیدونم چه سناریوی باید برقرار بکنم تا بشه مقدار کد شعبه را به لایه persistense منتقل کرد و اونجا با گذاشتن یک if ساده کانکشن مربوط به اون کد رو بخونم (برای همین پرسیدم آیا امکان تعریف متغیر سراسری در سطح تمام لایه ها وجودداره یا خیر) و اگر امکانش نیست به چه روشی میتونم مقدار یک متغیر خونده شده را از لایه UI به لایه Persistense جایی که کانکشن استرینگ خونده میشه منتقل بکنم
امیدوارم توضیحاتم رو با دقت بخونید تا دقیقا متوجه مشکل من بشید
بازهم مچکرم که پست های من رو پیگیری میکنید
یعنی واقعا راهکاری نداره؟؟؟؟؟
دوستان اظهار نظر بفرمایید
ببینید اگر من بتوانم یک متغیر گلوبال دذ سطح سولوشن تعریف بکنم، میتونم تو لایه ui مثلا کد شعبه رو بهش بدم و هر موقع خواست تو لایه persistense ، دیتابیس رو وصل بکنه یعنی AddDbContext ، با یک دستور if اون متغیر سراسری رو چک بکنه و بر اساس مقدارش دیتابیس مربوطه رو فراخوانی بکنه
ببین توی اون لایه ای که سرویس ایمیل رو ساختی
همونجا یه اینترفیس و یه کلاس ارث بری شده از اون بساز که توش یه تابع باشه باشه یه دیکشنری پرایویت و کار ها رو ردیف کن.
بعدش همینو توی سرویس ها AddScoped کن
یک اینترفیس ایجاد کردم
یک کلاس ازش ساختم که ارثبری بکنه
حالا این دیکشنری که میفرمایید چجوری باشه میشه نمونه کد بدید؟
اینو نفهمیدم: "یه تابع باشه باشه یه دیکشنری پرایویت و کار ها رو ردیف کن"
الو
کسی میتونه کمکم بکنه؟
????????????????
?
کدش طولانی میشه
فعلا نمیتونم براتون بنویسم
مهندس من تا جایی که درک کردم موضوع رو شما میخواهی یک اینترفیس بسازی که با دریافت کد مربوط به شعبه کاربر و if هایی که داخلش هست اسم اون کانکشن استرینگ رو بریزه تو یک متغیر string و نهایتا زمانی که میخواد تو لایه persistense کانکشن استرینگ رو بخونه، بجاش از متغیری که در این اینترفیس ایجاد شده اسمش رو بخونه
درسته؟
این رو بصورت تئوری در این حد متوجه شدم البته نمیدونم چقدر درست باشه
اما مشکل اصلیم تو پیاده سازیش اینه که تو این لایه persistense بهیچعنوان نمیتونی از هیچ کلاسی بخونی و ضمنا هنگام دیباگ به محض اینکه درخواستی میدی به دیتابیس قبل از خوندن هر کدی میره سراغ این AddContext و در نتیحه هر جایی هر کدی رو بخونی بی اثر هستش...
مهندس اصلانی گرامی
سلام و وقت بخیر
ظاهرا تو حل این مسئله تنها شما میتونید کمکم بکنید،
جسارتا وقت کردید کد راهنما رو برام بنویسید؟