در بیشتر مواقع نیازی به ارائه پروایدرهای پایگاه داده چندگانه ندارید. به عنوان مثال ، شما با پروایدرSQL Server شروع میکنید و نیازی به رفتن به پروایدر پایگاه داده دیگری نیست. در این پروژهی نمونه، ما باید چندین پروایدر را برای پشتیبانی از محیطهای مختلف استقرار اضافه کنیم. برخی از مشتریان ترجیح میدهند از پایگاه داده Windows Server و SQL Server و برخی دیگر از Linux و MySQL یا PostgreSQL استفاده کنند.
نظرات مطالب
آشنایی با NHibernate - قسمت پنجم
NH 3.0 پشتیبانی یکپارچهای را از LINQ ارائه میدهد و دیگر نیازی نیست مانند نگارش 2 آن پروایدر مخصوصی را جداگانه دریافت کرد. آن پروایدر قدیمی هم به نظر کنار گذاشته شده و از یک کتابخانهی پختهتر به نام Remotion Linq Library استفاده گردیده است (+).
در این نگارش برای دسترسی به IQueryable interface میتوان از متد session.Query استفاده کرد (بجای session.Linq نگارش قبلی).
در این نگارش برای دسترسی به IQueryable interface میتوان از متد session.Query استفاده کرد (بجای session.Linq نگارش قبلی).
متد ForEach در کلاس List از حلقه for معمولی استفاده میکنه و نه foreach:
public void ForEach(Action<T> action) { if (action == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); for (int index = 0; index < this._size; ++index) action(this._items[index]); }
public static void ForEach<T>(T[] array, Action<T> action) { if (array == null) throw new ArgumentNullException("array"); if (action == null) throw new ArgumentNullException("action"); for (int index = 0; index < array.Length; ++index) action(array[index]); }
foreach به دلیل استفاده از اشیای درون IEnumerable و درنتیجه اجرای دستورات بیشتر در هر حلقه کندتر عمل میکند.
اما! اگر هدف تنها بررسی سرعت اجرای حلقههای اشاره شده باشه متدهای بالا نتیجه درستی نشان نخواهد داد، چون عملیات انجام شده در حلقههای نشان داده شده با هم دقیقا یکسان نیست. بهتره که یه عملیات ثابت و مستقل از متغیرهای درگیر استفاده بشه تا نتایج دقیقتری بدست بیاد. مثلا یه چیزی مثل اکشن زیر:
() => { int a = 1; }
بهتره تو این تستها مشخصات دقیق سخت افزاری هم ارائه بشه تا مقایسهها بهتر انجام بگیره.
با این شرح با روشی که در مطلب Microbenchmark آورده شده آزمایشات رو دوباره انجام دادم و برای تعداد تکرار 100 میلیون اختلاف تمام حلقهها در حد چند میلی ثانیه بود که کاملا قابل صرفنظره!
نتایج برای حالات مختلف موجود تفاوتهای زیادی داشت اما درنسخه ریلیز نهایتا نتایج کلی این بود که حلقه for معمولی از همه سریعتر، سپس Array.ForEach و بعد متد ForEach در کلاس List و درنهایت ازهمه کندتر حلقه foreach بود.
من آزمایشات روی یک سیستم با پردازنده 4 هسته ای با کلاک 3.4 گیگاهرتز (AMD Phenom II 965) با ویندوز 7 و 32 بیتی با رم 4 گیگ (3.25 گیگ قایل استفاده)انجام دادم. متاسفانه تعداد تکرار بیشتر خطای OutOfMemory میداد.
نکته: اجرای تستهای این چنینی برای آزمایش کارایی و سرعت به شدت تحت تاثیر عوامل جانبی هستند. مثل میزان منابع در دسترس سخت افزاری، نوع سیستم عامل، برنامهها و سرویسهای در حال اجرا، و مهمتر از همه نوع نسخه بیلد شده از برنامه تستر (دیباگ یا ریلیز) و محل اجرای تست (منظور اجرا در محیط دیباگ ویژوال استودیو یا اجرای مستقل برنامه) و ... . (همونطور که آقای نصیری هم مطلبی مرتبط رو به اشتراک گذاشتند ^)
نظرات مطالب
آشنایی با CLR: قسمت دهم
دات نت فریمورک هم یک معضل بزرگ در زمینهی DLL hellدارد که برای حل مشکل در پخش کردن فایلها در جای جای هارد دیسک راه درازی در پیش است.
GAC به همین منظور تدارک دیده شد. در GAC میتوان چندین نگارش یک DLL دات نتی را ذخیره کرد، بدون اینکه برنامههای مختلف دات نتی با مشکل نصب یا ارتقاء مواجه شوند.
منظورتون از به صورت دستی چی هست؟ لطفا بیشتر توضیح بدید.
در ضمن در نظر داشته باشید که این بانک اطلاعاتی شامل Migration هم هست. بنابراین با هر آپدیتای که برای این پکیج منتشر میشه، بانک اطلاعاتی در برنامه شما هم به صورت خودکار آپدیت میشه بدون اینکه شما نیاز به اطلاع داشته باشید.
در این دوره، قالب تهیه یک پروژه جدید WPF مبتنی بر EF Code first را دریافت خواهید کرد که دارای این مشخصات است:
1- اعتبارسنجی یکپارچه با EF Code first
3- به همراه مباحثی مانند تعریف کاربران، تعریف سطوح دسترسی و همچنین راهبری بین صفحات برنامه با درنظر گرفتن این مسایل به کمک تنها افزودن یک ویژگی به نام PageAuthorization به ابتدای تعریف کلاس یک صفحه
4- دارای سیستم خودکار پیغام دهی به کاربر در صورتیکه قصد حرکت به صفحهای دیگر را داشته باشد؛ اما تغییرات صفحه جاری ذخیره نشدهاند.
5- قالب پروژه جدید تدارک دیده شده، به صورت خودکار لایه بندیهای برنامه را تدارک خواهد دید (شامل DataLayer، DomainClasses، ServiceLayer و غیره)
6- به همراه سیستم DbContext یکپارچه با مباحثی مانند یکسان سازی ی و ک در برنامه به صورت خودکار و نمایش مشکلات اعتبارسنجی دادهها به کاربر بدون نیازی به کد نویسی اضافه.
7- این قالب پروژه با کتابخانههای زیر یکپارچه است:
Entity Framework Code First
Fody (جهت اعمال مسایل AOP برای کاهش تدارک کدهای INotifyPropertyChanged در برنامه)
MahApps.Metro (برای نمایش قالب مترو سازگار با دات نت 4)
Microsoft.SqlServer.Compact.4 (بانک اطلاعاتی پیش فرض برنامه دسکتاپ تدارک دیده شده)
MvvmLight (پایه مباحث MVVM بکارگرفته شده در برنامه)
StructureMap (جهت پیاده سازی مباحث تزریق وابستگیها در برنامه)
1- اعتبارسنجی یکپارچه با EF Code first
2- دارای سیستم راهبری (Navigation) بین صفحات با قابلیت تزریق خودکار وابستگیها توسط کتابخانه StructureMap
3- به همراه مباحثی مانند تعریف کاربران، تعریف سطوح دسترسی و همچنین راهبری بین صفحات برنامه با درنظر گرفتن این مسایل به کمک تنها افزودن یک ویژگی به نام PageAuthorization به ابتدای تعریف کلاس یک صفحه
4- دارای سیستم خودکار پیغام دهی به کاربر در صورتیکه قصد حرکت به صفحهای دیگر را داشته باشد؛ اما تغییرات صفحه جاری ذخیره نشدهاند.
5- قالب پروژه جدید تدارک دیده شده، به صورت خودکار لایه بندیهای برنامه را تدارک خواهد دید (شامل DataLayer، DomainClasses، ServiceLayer و غیره)
6- به همراه سیستم DbContext یکپارچه با مباحثی مانند یکسان سازی ی و ک در برنامه به صورت خودکار و نمایش مشکلات اعتبارسنجی دادهها به کاربر بدون نیازی به کد نویسی اضافه.
7- این قالب پروژه با کتابخانههای زیر یکپارچه است:
Entity Framework Code First
Fody (جهت اعمال مسایل AOP برای کاهش تدارک کدهای INotifyPropertyChanged در برنامه)
MahApps.Metro (برای نمایش قالب مترو سازگار با دات نت 4)
Microsoft.SqlServer.Compact.4 (بانک اطلاعاتی پیش فرض برنامه دسکتاپ تدارک دیده شده)
MvvmLight (پایه مباحث MVVM بکارگرفته شده در برنامه)
StructureMap (جهت پیاده سازی مباحث تزریق وابستگیها در برنامه)
با کمک Fluent NHibernate میتوان نگاشتها را به دو صورت خودکار و یا دستی تعریف کرد. در حالت خودکار، روابط بین کلاسها بررسی شده و بدون نیاز به تعریف هیچگونه ویژگی (attribute) خاصی بر روی فیلدها، امکان تشخیص خودکار حالتهای کلید خارجی، روابط یک به چند، چند به چند و امثال آن وجود دارد. یا اگر نیاز باشد تا اسکریپت تولیدی جهت به روز رسانی بانک اطلاعاتی، طول خاصی را به فیلدی اعمال کند میتوان از ویژگیهای NHibernate validator استفاده کرد؛ مانند تعریف طول و نال نبودن یک فیلد که علاوه بر بکارگیری اطلاعات آن در حین تعیین اعتبار ورودی دریافتی، بر روی نحوهی به روز رسانی بانک اطلاعاتی هم تاثیر گذار است:
public class Product
{
public virtual int Id { set; get; }
[Length(120)]
[NotNullNotEmpty]
public virtual string Name { get; set; }
public virtual decimal UnitPrice { get; set; }
}
public class ProductCustomMappings : IAutoMappingOverride<Product>
{
public void Override(AutoMapping<Product> mapping)
{
mapping.Id(u => u.Id).GeneratedBy.Identity(); //ضروری است
mapping.Map(p => p.Name).Unique();
}
}
مطالب
مروری سریع بر neo4j
neo4j یک بانک اطلاعاتی گراف پایه است که جزو بانکهای اطلاعاتی no-sql طبقه بندی میشود. سرعت بسیار بالا و امکان اجرای کوئریهای پیچیده، از برجستهترین ویژگیهای این بانک اطلاعاتی است.
در زیر برخی دستورات ابتدایی آن آورده شده است.
مثال واقعی:
در مثال بالا یک آبجکت با نوع یوزر را ایجاد کردیم. با اینکار در واقع تایپ یوزر را هم به neo4j معرفی کردیم. البته هر اسمی را میتوانیم جای یوزر بگذاریم.
بازیابی یک آبجکت
برای بازیابی یک آبجکت، از فرم ساده زیر استفاده میشود:
میتوانیم برای بازیابی شرط هم تعیین کنیم:
ایجاد رابطه بین دو شیء
برای ایجاد رابطه بین دو شیء، از فرم زیر استفاده میکنیم:
اسم LIKE را ما بر روی این رابطه گذاشتیم و البته هر اسم دیگری را نیز میتوانستیم بگذاریم و الزامی هم برای نوشتن با حروف بزرگ نبود. فقط برای راحتتر تفکیک کردن از سایر نوع آبجکتها، این اسم را با حرف بزرگ نوشتیم .
برای بازیابی همه مواردی که لایک شدهاند:
برای بازیابی همه مواردی که یک یوزر خاص لایک کردهاست:
برای بازیابی دو طرفی که در رابطه LIKE شرکت داشتهاند، از فرم زیر استفاده میکنیم:
میتوانید قسمت شرط را هم اضافه کنید و برای مثال همه کاربرانی را که از یک تاریخ خاص ایجاد شدهاند و چیزی را لایک کردهاند، بدست بیاورید:
بهترین کاربرد neo4j استفاده به عنوان مکمل برای بانک اطلاعاتیهای دیگر مثل مونگو و کاساندرا است؛ به این صورت که دیتای اصلی در دیتابیس مونگو یا کاساندرا ذخیره گردد و ایندکس این دیتاها به همراه چند پارامتر کلیدی که در کوئریها استفاده زیادی دارد در neo4j ذخیره گردد. اکثر کوئریها بر روی neo4j اجرا شوند و با استفاده از کلیدهای یافته شده، دیتای اصلی از بانک اطلاعاتی اصلی دریافت شود. این روش در پروژههای بسیار بزرگ (مثل شبکههای اجتماعی) کاربرد فراوانی دارد. همین شیوه برای استفاده از ElasticSearch نیز بسیار مرسوم است.
برای کار با neo4j آدرس http://127.0.0.1:7474 را درمرورگر وارد کنید و سپس وارد ویرایشگر کوئری شوید. برای بار اول، neo4j از شما نام کاربری و رمز عبوری را درخواست میکند. این نام و رمز عبور، هنگام نصب تعیین میشود. معمولآ نام کاربری آن neo4j است.
در زیر برخی دستورات ابتدایی آن آورده شده است.
ایجاد یک آبجکت و یا ویرایش آن
برای ساخت یک آبجکت و یا ویرایش آن، باید از فرم کوئری زیر استفاده کنیم. این مرحله معادل ساخت جدول در بانکهای اطلاعاتی رابطهای است.
CREATE (VariableName:objectType { guid: {keyInMainDB }, property1 :value1 ,property2 : value2 ,... )
فرم زیر، هم برای ایجاد کاربرد دارد و هم برای ویرایش. چون این فرم هر دو حالت را باهم پوشش میدهد، بیشتر استفاده میشود. هر چند در مواقعی که میخواهیم تعداد زیادی دیتا وارد بانک کنیم، حالت قبل سرعت بالاتری دارد.
MERGE (VariableName:objectType { guid: keyInMainDB }) SET VariableName +={property1: value1,property2: value2,...}
MERGE (object:User { guid: 1353554 }) SET object +={username:"nasser" ,time_created: 1522480294 }
مقادیر عددی مستقیم، و موارد رشتهای با کوتیشن به خواص نسبت داده شدند. اسم خواص را هم ما انتخاب کردیم. علاوه بر عدد و رشته، neo4j از آرایه هم به عنوان نوع داده ورودی پشتیبانی میکند.
بازیابی یک آبجکت
برای بازیابی یک آبجکت، از فرم ساده زیر استفاده میشود:
match (VariableName:objectType ) return VariableName
برای بازیابی آبجکتی که در بالا درج شد، از مثال واقعی زیر استفاده میکنیم:
match (object:User { guid: 1353554 }) return object
match (object:User ) where object.time_created>1522480293 return object
ایجاد رابطه بین دو شیء
برای ایجاد رابطه بین دو شیء، از فرم زیر استفاده میکنیم:
MATCH (v1:objectType1 {guid: guid1}), (v2:objectType2 {guid: guid2}) MERGE (v1)-[:RelationshipName]->(v2)
برای مثال واقعی میتوانید حالتی را در نظر بگیرید که یک کاربر، کاربر دیگری را در شبکه اجتماعی دنبال میکند. در اینجا رابطه دنبال کردن بین دو کاربر ایجاد میشود. یا حالتی که یک فرد، یک متن یا تصویر را لایک میکند، در اینجا بین آبجکت کاربر و آن آبجکت متن یا تصویر، رابطه لایک کردن ایجاد میشود.
مثال واقعی برای لایک کردن:
MATCH (usr:User {guid: 1353554 }),(img:Image {guid: 88554 }) MERGE (usr)-[:LIKE]->(img)
برای بازیابی کاربرهایی که مواردی را لایک کردهاند از فرم زیر استفاده میکنیم:
MATCH (usr:User)-[r:LIKE]-() Return usr
MATCH ()-[r:LIKE]-(n) Return n
MATCH (usr:User{guid:1353554 })-[r:LIKE]-(n) Return n
MATCH p=()-[r:LIKE]->() RETURN p
MATCH (usr:User )-[r:LIKE]-(n) where usr.time_created>1522480293 Return usr
سراسری هست؛ هرچند میتوانید کلید کش را بر اساس user-id تعیین کنید و یا از سشن استفاده کنید.