CodeShot

ProjectTo() در مقابل Map()

ProjectTo() مستقیماً روی یک IQueryable عمل می‌کند و Expression نگاشت را به کوئری SQL ترجمه می‌کند تا فقط ستون‌های لازم از دیتابیس خوانده شوند، در حالی که Map() روی اشیاء موجود در حافظه (In-Memory) کار می‌کند و ابتدا باید کل موجودیت از دیتابیس خوانده شده باشد.

ویژگیProjectTo()Map()
ورودیIQueryableشیء در حافظه
ترجمه به SQLبلهخیر
کارایی برای کوئری دیتابیسبهترضعیف‌تر

کِی از ProjectTo() استفاده کنیم؟

وقتی مستقیماً از یک DbSet یا IQueryable در EF Core به DTO نگاشت می‌کنید و می‌خواهید فقط فیلدهای لازم از دیتابیس واکشی شوند.

کِی از Map() استفاده کنیم؟

وقتی داده از قبل در حافظه است (مثلاً نتیجه یک متد یا لیست موجود) و نیازی به ترجمه به کوئری SQL ندارید.

مثال ProjectTo()

var dtos = await context.Orders
    .ProjectTo<OrderDto>(mapper.ConfigurationProvider)
    .ToListAsync();
// فقط ستون‌های لازم SELECT می‌شوند

مثال Map()

var orders = await context.Orders.ToListAsync();
var dtos = mapper.Map<List<OrderDto>>(orders);
// کل موجودیت از دیتابیس خوانده شده است

اشتباه رایج

اشتباه رایج استفاده از Map() مستقیم بعد از ToListAsync() به‌جای ProjectTo() قبل از اجرای کوئری است؛ این کار باعث می‌شود ستون‌های غیرضروری هم از دیتابیس خوانده شوند و کارایی کوئری به‌طور غیرضروری افت کند.

جمع‌بندی

برای نگاشت مستقیم از یک کوئری دیتابیس همیشه ترجیحاً از ProjectTo() و برای نگاشت داده‌ای که از قبل در حافظه است از Map() استفاده کنید.