تامین مقادیر پارامترها در حین نگاشت‌های AutoMapper
متد Project To را می‌توان به عنوان متد پیش فرض حین کار با ORMها درنظر گرفت؛ با این مزایا:
- جلوگیری از Lazy loading اشتباه
- کاهش تعداد فیلدهای بازگشت داده شده‌ی از دیتابیس و محدود ساختن آن‌ها به خواصی که قرار است نگاشت شوند. در حالت معمولی استفاده‌ی از متد Mapper.Map، تمام فیلدهای مدل بارگذاری شده و سپس در سمت کلاینت توسط AutoMapper نگاشت خواهند شد. اما در حالت استفاده‌ی از متد ویژه‌ی Project To، کوئری SQL ارسالی به بانک اطلاعاتی نیز مطابق نگاشت تعریف شده، تغییر کرده و خلاصه خواهد شد.

در این حالت یک چنین سناریویی را درنظر بگیرید. مدل متناظر با جدول بانک اطلاعاتی ما چنین ساختاری را دارد:
public class UserModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
و اطلاعاتی که قرار است در رابط کاربری نمایش داده شوند، به این شکل تعریف شده‌اند:
public class UserViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string UserIdentityName { get; set; }
}
در اینجا خاصیت UserIdentityName قرار است در زمان اجرا، برای مثال توسط مقدار User.Identity.Name تامین شود و در حالت کلی، خاصیت یا خاصیت‌های ثابتی را داریم که نیاز است در حین نگاشت انجام شده، در زمان اجرا مقدار ثابت خود را دریافت کنند.


تعریف نگاشت‌های پارامتری

برای حل این مساله، از روش زیر استفاده می‌شود:
 string userIdentityName = null;
this.CreateMap<UserModel, UserViewModel>()
 .ForMember(d => d.UserIdentityName, opt => opt.MapFrom(src => userIdentityName));
ابتدا یک متغیر خالی را تعریف می‌کنیم. از آن جهت تهیه‌ی یک lambda expression صحیح در قسمت MapFrom استفاده خواهیم کرد. کار این متغیر خالی، تهیه‌ی یک عبارت جایگزین شونده‌ی در زمان اجرا است.
اکنون جهت استفاده‌ی از این متغیر با قابلیت جایگزینی، می‌توان به نحو ذیل عمل کرد:
var uiUsers = users.AsQueryable()
                   .Project()
                   .To<UserViewModel>(new { userIdentityName = "User.Identity.Name Value Here" })
                   .ToList();
در اینجا لیست کاربران بانک اطلاعاتی، به لیست UserViewModel‌ها نگاشت شده و همچنین مقدار خاصیت UserIdentityName آن‌ها نیز از پارامتری که به متد Project To ارسال گردیده‌است، تامین خواهد شد.


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید.
  • #
    ‫۲ سال قبل، شنبه ۲۲ مرداد ۱۴۰۱، ساعت ۱۳:۰۲
    نکته تکمیلی
    در صورتیکه به زمانِ الان، برای پارامتر هاتون نیاز داشتید اونو از طریق سرویس پاس بدید و متغیر رو داخل Profile به این صورت تعریف نکنید:
    public class MappingProfile : Profile
    {
        var now = DateTime.Now;
    }
    چون همون بار اول که پروژه اجرا میشه، مقدار دهی میشه و زمانش تغییر پیدا نمیکنه، DateTime.Now باید هربار از طریق سرویس از نو مقداردهی بشه.
    public class MappingProfile : Profile
    {
        DateTime now = default;
    }
    return _products
                .AsNoTracking()
                .ProjectTo<ProductInfoViewModel>(
                    configuration: _mapper.ConfigurationProvider,
                    parameters: new { now = DateTime.Now }
                ).SingleOrDefaultAsync(x => x.Id == id);