Skip to content

Yansıtma

Umut Ozel edited this page Apr 20, 2017 · 4 revisions

Yansıtma işlemi, tamamen hazır bir kopyalama kodu ile bir nesneyi bir diğerine kopyalar. Bu ifadeyi IQueryable'ın Select metodunu çağırırken parametre olarak kullanacağız. Yani bizim kopyalama kodlarımızda bulunan MapContext parametrelerinin çıkarılması ve yerlerine gerçek kopyalama kodlarının yerleştirilmesi gerekiyor.

BatMap bizim için bu işi yapıyor, ancak kayıt işlemini özel bir ifade ile yaptıysanız, kodunuzda ilişkileri kopyalamak için MapContext metodlarını (Map ve MapToList) kullanmanız gerekiyor. Böylece BatMap sorguyu yansıtırken hangi ilişkileri dahil edeceğine ve bunlar için gerekli kopyalama kodlarını koyacağına karar verebilsin. Bunu söylemişken, ne olursa olsun (ilişki sorguda dahil edilmemiş dahi olsa) bu ilişkinin kopyalanmasını istiyorsanız manuel kopyalama yapabilirsiniz.

İşte sorgu yansıtmasında kullanabileceğimiz yöntemler.

  • BatMap'in hangi ilişkilerin sorguya dahil edildiğini tespit etmesini sağlayabilirsiniz.
public IQueryable<TOut> ProjectTo<TOut>(IQueryable query, bool checkIncludes = true)

// checkIncludes için false değeri geçtiğinizde, BatMap tüm ilişkileri yansıtacaktır. 
// dikkatli olun, bu bir StackOverflowException hatasına sebep olabilir..
// (eğer bir yerlerde iki-yönlü ilişkiniz varsa -Order.OrderDetails ve OrderDetail.Order gibi).
config.ProjectTo<CustomerDTO>(context.Customers, false);

  • BatMap'e hangi ilişkileri dahil etmesini istediğinizi söyleyebilirsiniz.
public IQueryable<TOut> ProjectTo<TIn, TOut>(IQueryable<TIn> query, params Expression<Func<TIn, object>>[] includes)

// bu kod sadece OrderDetails, Product ve Supplier ilişkilerini yansıtacaktır.
config.ProjectTo<Order, OrderDTO>(query, o => o.OrderDetails.Select(od => od.Product.Supplier));

  • IncludePath kullanarak hangi ilişkileri dahil etmek istediğinizi söyleyebilirsiniz. Sorgulara dahil edilecek ilişkilere dinamik karar verdiğini durumlar için kullanışlı olacaktır.

IncludePath çok basit bir sınıftır, sadece dahil edilmiş ilişki adını ve bu ilişkinin alt dahil ilişkilerini tutar. Bu yapıyı aşağıdaki gibi görsele dökebiliriz:

Include Path

public IQueryable<TOut> ProjectTo<TOut>(IQueryable query, params IncludePath[] includes)

// OrderDetails.Product ilişkilerini yansıtmamıza dahil ettik.
config.ProjectTo<OrderDTO>(query, new IncludePath("OrderDetails", new List<IncludePath> { new IncludePath("Product") }));

  • Eğer sorgu yansıtma kodunuz çok sık çağırılacaksa ve sorguyu ziyaret edip modifiye etmenin bir performans kaybına yol açacağını düşünüyorsanız (büyük ihtimal açmayacaktır), tam ihtiyacınız olan yapıyı da sunuyoruz. Sorgu olmadan da yansıtma ifadesini oluşturup ileride kullanmak için önbelleğe alabilirsiniz (BatMap'de arka planda bu metodları kullanıyor).
public Expression<Func<TIn, TOut>> GetProjector<TIn, TOut>(bool includeNavigations = true)

// yansıtma ifadesini bir statik alana koyuyoruz.
_projector = config.GetProjector<Order, OrderDTO>(false);

// sonra bu ifadeyi yansıtma için kullanabiliyoruz.
var dtoQuery = query.Select(_projector);

  • Yansıtma ifadesinde hangi ilişkilerin bulunmasını istediğimizi söyleyebiliyoruz.
public Expression<Func<TIn, TOut>> GetProjector<TIn, TOut>(params Expression<Func<TIn, object>>[] includes)

_projector = config.GetProjector<Order, OrderDTO>(query, o => o.OrderDetails.Select(od => od.Product.Supplier));

var dtoQuery = query.Select(_projector);

  • IncludePath kullanarak hangi ilişkileri yansıtma ifademize dahil etmek istediğimizi söyleyebiliyoruz.
public Expression<Func<TIn, TOut>> GetProjector<TIn, TOut>(params IncludePath[] includes)

_projector = config.GetProjector<Order, OrderDTO>(query, 
    new IncludePath("OrderDetails", new List<IncludePath> { new IncludePath("Product") })
);

var dtoQuery = query.Select(_projector);

Statik API

Mapper statik sınıfı sadece ProjectTo metodlarını içerir, ve bunların hepsi genişletme metodlarıdır 💯

public static IQueryable<TOut> ProjectTo<TOut>(this IQueryable query, bool checkIncludes = true)

public static IQueryable<TOut> ProjectTo<TIn, TOut>(this IQueryable<TIn> query, params Expression<Func<TIn, object>>[] includes)

public static IQueryable<TOut> ProjectTo<TOut>(this IQueryable query, params IncludePath[] includes)

🦇Nasıl çalışır?🦇