نظرات مطالب
آشنایی با NHibernate - قسمت هشتم
ابزار حرفه‌ای مشاهده خروجی NHibernate برنامه زیر است (که در جهت دیباگ کار بسیار مفید است):
NHProf
کار کردن با آن هم بسیار ساده است. فایل How to use.txt آن‌را مطالعه کنید..
نظرات مطالب
آشنایی با NHibernate - قسمت هشتم
جناب نصیری عزیز
از شما به خاطر مطالب بسیار مفیدتان قدردانی می‌کنم
اگر امکان دارد طریقه استفاده از NHibernate در Windows Form (نمایش Objectها در Grid و کار با ابزارهای گزارش‌گیری و ...) را نیز آموزش دهید.
پاینده باشید.
نظرات مطالب
آشنایی با NHibernate - قسمت ششم
تشخیص روابط بین جداول یعنی همان mapping خودکار،‌ یعنی همان نحوه‌ی تعریف کلاس‌های شما و برقراری روابطی که در طی چند قسمت مثال زده شد. سیستم پیش فرض NHibernate بر اساس اول طراحی کلاس‌ها و بعد ایجاد ارتباط با دیتابیس است که اینجا به صورت خودکار صورت می‌گیرد.
برای مثال در قسمت هشتم یک سیستم many-to-many مثال زده شده است به همراه کوئری‌هایی از نوع Linq . اینجا فقط تعریف کلاس‌هایی که بیانگر روابط many-to-many باشند مهم است؛ نحوه‌ی نگاشت خودکار آن‌ها به دیتابیس کار Fluent NHibernate است. (از این نوع مثال‌ها در هر قسمت پیاده سازی شده)
جزئیات ریز نحوه‌ی نگاشت خودکار با مطالعه‌ی سورس کتابخانه NHibernate و مشتقات آن قابل درک است (برای علاقمندان).
ضمنا فرقی نمی‌کند از Linq قسمت پنجم استفاده کنید یا هر روش موجود دیگری برای کوئری گرفتن (زمانیکه Linq هست و نگارش‌های جدید آن برای NHibernate پیشرفت زیادی داشته، چرا روش‌های دیگر؟).
نظرات مطالب
آشنایی با NHibernate - قسمت اول
درباره entity های ماکروسافت هم اگر امکانش هست بنویسید.
فناوری های LINQ to entity و ADO.net entity
برای کسی که فقط با MSSQL کار میکند،آیا فناوری های بالا کمبودی نسبت به NHibernate دارند؟
منظور از هاست های medium trust چیست،یعنی ORM ها را نمی توان روی آنها اجرا کرد؟

-;{@
نظرات مطالب
5 دلیل برای استفاده از یک ابزار ORM
سلام جناب نصیری.
آیا تجربه ای در ضمینه Telerik ORM دارا هستید؟
قابل رقابت با EF , nhibernate , llblgen هست؟
ایا شما nettiers که یک Template برای Codesmith هست را یک ORM به حساب می آورید؟
با تشکر.
مطالب
چگونه در یک پروژه سورس باز مشارکت کنیم؟
مشارکت در پروژه‌های سورس باز الزاما به معنای هدیه کدهای جدیدی به آن پروژه یا حتی مشارکت مالی در آن نیست. در ادامه لیستی از مواردی را مرور خواهیم کرد که سبب زنده نگه داشته شدن یک پروژه سورس باز خواهند شد:

مشارکت در نگهداری پروژه
  • مشکلی را در این کتابخانه پیدا کرده‌اید؟ آن‌را در سیستم bug tracking پروژه گزارش کنید و بی‌تفاوت از کنار آن عبور نکنید.
  • مشکلی برطرف شده است؟ بررسی کنید، آیا واقعا این تغییرات مفید بوده است یا خیر و نتیجه را اعلام کنید.

بهبود کدهای موجود
  • در بهترین حالت، کدی را جهت رفع یک مشکل ارسال کنید. همچنین در این حالت سعی کنید یک مطلب جدید را ایجاد کرده و در مورد کدهای خود توضیح دهید. برای ارسال کدی جدید بهتر است تنها قسمت‌های تغییر کرده را ارسال کنید و اصطلاحا باید بتوانید توسط قابلیت‌های سورس کنترل‌ها یک patch را تهیه نمائید.
  • یک unit test جدید را به پروژه اضافه کنید. یک مثال جدید را برای قسمتی خاص تهیه نمائید.
  • ثوابت برنامه را به زبان‌های دیگر ترجمه کنید.
  • یک گزینه و قابلیت جدید را درخواست دهید.

بهبود مستندات پروژه
  • اگر توضیحات قسمت‌های مختلف و commentهای ارائه شده به نظر شما کافی نیست؛ آن‌ها را تکمیل کرده و یک patch برای آن ارائه دهید.
  • مستندات موجود را تکمیل کنید یا بهبود ببخشید.
  • یک مقاله‌ی جدید در مورد نحوه‌ی استفاده از آن پروژه بنویسید.
  • یک ویدیوی ساده آموزشی را در مورد آن تهیه کنید.

مشارکت در انجمن‌ها و شبکه‌های اجتماعی
  • به لیست سؤالات مطرح شده در یک پروژه مراجعه کرده و در آن مشارکت کنید. سعی کنید حضور مثبتی داشته باشید.
  • به دیگران در مورد وجود این پروژه اطلاع رسانی کنید.
  • اگر پروژه مفیدی است، به دیگران بگوئید این پروژه چقدر بر روی کار شما تاثیر داشته است و چه برنامه‌هایی را از طریق آن پیش برده‌اید.
 
مطالب
نوروز مبارک!

می‌گن لحظه تحویل سال نو، مشغول به هر کاری که باشی تا پایان سال سرت به همان گرم خواهد بود. به همین جهت سال نو رو با یک سری ویدیوی رایگان ASP.NET MVC 3 که به سفارش و هزینه مایکروسافت توسط Pluralsight تهیه شده، شروع می‌کنیم. باشد تا پایان سال به همین منوال ادامه یابد!
سال نو مبارک!

مطالب
نگاشت IDictionary در Fluent NHibernate

نگاشت خودکار مجموعه‌ها در Fluent NHibernate ساده است و نیاز به تنظیم خاصی ندارد. برای مثال IList به صورت خودکار به Bag ترجمه می‌شود و الی آخر.
البته شاید سؤال بپرسید که این Bag از کجا آمده؟ کلا 6 نوع مجموعه در NHibernate پشتیبانی می‌شوند که شامل Array، Primitive-Array ، Bag ، Set ، List و Map هستند؛ این‌ اسامی هم جهت حفظ سازگاری با جاوا تغییر نکرده‌اند و گرنه معادل‌های آن‌ها در دات نت به این شرح هستند:
Bag=IList
Set=Iesi.Collections.ISet
List=IList
Map=IDictionary

البته در دات نت 4 ، ISet هم به صورت توکار اضافه شده، اما NHibernate از مدت‌ها قبل آن‌را از کتابخانه‌ی Iesi.Collections به عاریت گرفته است. مهم‌ترین تفاوت‌های این مجموعه‌ها هم در پذیرفتن یا عدم پذیرش اعضای تکراری است. Set و Map اعضای تکراری نمی‌پذیرند.
در ادامه می‌خواهیم طرز کار با Map یا همان IDictionary دات نت را بررسی کنیم:

الف) حالتی که نوع کلید و مقدار (در یک عضو Dictionary تعریف شده)، Entity نیستند
using System.Collections.Generic;

namespace Test1.Model12
{
public class User
{
public virtual int Id { set; get; }
public virtual string Name { get; set; }
public virtual IDictionary<string, string> Preferences { get; set; }
}
}

نحوه تعریف نگاشت که مبتنی است بر مشخص سازی تعاریف کلید و مقدار آن جهت تشکیل یک Map یا همان Dictionary :
using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;

namespace Test1.Model12
{
public class UserMapping : IAutoMappingOverride<User>
{
public void Override(AutoMapping<User> mapping)
{
mapping.Id(x => x.Id);
mapping.HasMany(x => x.Preferences)
.AsMap<string>("FieldKey")
.Element("FieldValue", x => x.Type<string>().Length(500));
}
}
}

خروجی SQL متناظر:
create table "User" (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
primary key (Id)
)

create table Preferences (
User_id INT not null,
FieldValue NVARCHAR(500) null,
FieldKey NVARCHAR(255) not null,
primary key (User_id, FieldKey)
)

alter table Preferences
add constraint FKD6CB18523B1FD789
foreign key (User_id)
references "User"

ب) حالتی که مقدار، Entity است
using System.Collections.Generic;

namespace Test1.Model13
{
public class User
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IDictionary<string, Property> Properties { get; set; }
}

public class Property
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Value { get; set; }
public virtual User User { get; set; }
}
}

نحوه تعریف نگاشت:
using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;

namespace Test1.Model13
{
public class UserMapping : IAutoMappingOverride<User>
{
public void Override(AutoMapping<User> mapping)
{
mapping.Id(x => x.Id);
mapping.HasMany<Property>(x => x.Properties)
.AsMap<string>("FieldKey")
.Component(x => x.Map(c => c.Id));
}
}
}
خروجی SQL متناظر:
create table "Property" (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
Value NVARCHAR(255) null,
User_id INT null,
primary key (Id)
)

create table "User" (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
primary key (Id)
)

create table Properties (
User_id INT not null,
Id INT null,
FieldKey NVARCHAR(255) not null,
primary key (User_id, FieldKey)
)

alter table "Property"
add constraint FKF9F4D85A3B1FD7A2
foreign key (User_id)
references "User"

alter table Properties
add constraint FK63646D853B1FD7A2
foreign key (User_id)
references "User"

ج) حالتی که کلید، Entity است
using System;
using System.Collections.Generic;

namespace Test1.Model14
{
public class FormData
{
public virtual int Id { get; set; }
public virtual DateTime? DateTime { get; set; }
public virtual IDictionary<FormField, string> FormPropertyValues { get; set; }
}

public class FormField
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
}

نحوه تعریف نگاشت:
using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;

namespace Test1.Model14
{
public class FormDataMapping : IAutoMappingOverride<FormData>
{
public void Override(AutoMapping<FormData> mapping)
{
mapping.Id(x => x.Id);
mapping.HasMany<FormField>(x => x.FormPropertyValues)
.AsEntityMap("FieldId")
.Element("FieldValue", x => x.Type<string>().Length(500))
.Cascade.All();
}
}
}
خروجی SQL متناظر:
create table "FormData" (
Id INT IDENTITY NOT NULL,
DateTime DATETIME null,
primary key (Id)
)

create table FormPropertyValues (
FormData_id INT not null,
FieldValue NVARCHAR(500) null,
FieldId INT not null,
primary key (FormData_id, FieldId)
)

create table "FormField" (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
primary key (Id)
)

alter table FormPropertyValues
add constraint FKB807B9C090849E
foreign key (FormData_id)
references "FormData"

alter table FormPropertyValues
add constraint FKB807B97165898A
foreign key (FieldId)
references "FormField"

یک مثال عملی:
امکانات فوق جهت طراحی قسمت ثبت اطلاعات یک برنامه «فرم ساز» مبتنی بر Key-Value بسیار مناسب هستند؛ برای مثال:
برنامه‌ای را در نظر بگیرید که می‌تواند تعدادی خدمات داشته باشد که توسط مدیر برنامه قابل اضافه شدن است؛ برای نمونه خدمات درخواست نصب نرم افزار، خدمات درخواست تعویض کارت پرسنلی، خدمات درخواست مساعده، خدمات ... :
public class Service
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<ServiceFormField> Fields { get; set; }
public virtual IList<ServiceFormData> Forms { get; set; }
}

برای هر خدمات باید بتوان یک فرم طراحی کرد. هر فرم هم از یک سری فیلد خاص آن خدمات تشکیل شده است. برای مثال:
public class ServiceFormField
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual bool IsRequired { get; set; }
public virtual Service Service { get; set; }
}

در اینجا نیازی نیست به ازای هر فیلد جدید واقعا یک فیلد متناظر به دیتابیس اضافه شود و ساختار آن تغییر کند (برخلاف حالت dynamic components که پیشتر در مورد آن بحث شد).
اکنون با داشتن یک خدمات و فیلدهای پویای آن که توسط مدیربرنامه تعریف شده‌اند، می‌توان اطلاعات وارد کرد. مهم‌ترین نکته‌ی آن هم IDictionary تعریف شده است که حاوی لیستی از فیلدها به همراه مقادیر وارد شده توسط کاربر خواهد بود:
public class ServiceFormData
{
public virtual int Id { get; set; }
public virtual IDictionary<ServiceFormField, string> FormPropertyValues { get; set; }
public virtual DateTime? DateTime { get; set; }
public virtual Service Service { get; set; }
}

در مورد نحوه نگاشت آن هم در حالت «ج» فوق توضیح داده شد.