2016-04-11 22 views
3

Birim İşi ile bir havuz modeli oluşturmak için here örneğini kullanıyorum. Bu yöntem denir Şu andaRepository Pattern Yalnızca İstenen Sütunları Geri Al

public class GenericRepository<TEntity> where TEntity : class 
{ 
    internal AdminDbContext context; 
    internal DbSet<TEntity> dbSet; 

    public GenericRepository(AdminDbContext context) 
    { 
     this.context = context; 
     this.dbSet = context.Set<TEntity>(); 
    } 

    public virtual IEnumerable<TEntity> Get(
     Expression<Func<TEntity, bool>> filter = null, 
     Func<TEntity, TEntity> selector = null, 
     Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
     string includeProperties = "") 
    { 
     IQueryable<TEntity> query = dbSet; 

     if (filter != null) 
     { 
      query = query.Where(filter); 
     } 


     foreach (var includeProperty in includeProperties.Split 
      (new char[] { ','}, StringSplitOptions.RemoveEmptyEntries)) 
     { 
      query = query.Include(includeProperty); 
     } 

     if (orderBy != null) 
     { 
      return orderBy(query).ToList(); 
     } 
     else 
     { 
      return query.ToList(); 
     } 
    } 

, veritabanından tüm kayıtları yüklenirken ve sütun seçimi bellekte yapılır: kodunda

, genel Get yöntemi yoktur.

Benim sorum, burada veritabanı yönteminde yalnızca istenen sütunların seçilebilmesi için sütun adlarını bu yönteme dinamik olarak aktarmama izin veren Get yöntemini nasıl genişletebilirim?

denedim:

  • virgül ile istenilen sütun ayrılmış değerler bir dize parametresi kabul etme ama varlığa onları map olamayacağını.
  • Hata veren aynı filtre türünde bir parametre oluşturma.
+1

kullanma '.Select()'. – CodeCaster

cevap

1

Bu uzun bir yanıt türüdür, ancak burada bunu yapmak için oluşturduğum bir uzantı yöntemidir. Bu durumda bir nesne döndürüyorum çünkü bu sadece json'u döndürmek için webAPI'da kullanılır ve belirli bir türe ihtiyacım yoktur, ancak bu genel bir varlık türünü döndürmek için kolayca uyarlanabilir.

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using Newtonsoft.Json.Linq; 

namespace Your.Extensions 
{ 
    public enum PropertyFormat 
    { 
     AsIs, 
     PascalCase, 
     CamelCase 
    } 

    public static class DataShapingExtensions 
    { 
     public static object ToDataShape<ObjectIn>(this ObjectIn objectToShape, string fields, PropertyFormat propertyFormat = PropertyFormat.AsIs) where ObjectIn : class 
     { 
      var listOfFields = new List<string>(); 

      if (!string.IsNullOrWhiteSpace(fields)) 
      { 
       listOfFields = fields.ToLower().Split(',').ToList(); 
      } 

      if (listOfFields.Any()) 
      { 
       var objectToReturn = new JObject(); 

       //==== 
       var enumerable = objectToShape as IEnumerable; 

       if (enumerable != null) 
       { 
        var listOfObjects = new List<JObject>(); 

        foreach (var item in enumerable) 
        { 
         var objectToReturn2 = new JObject(); 

         listOfFields.ForEach(field => 
         { 
          try 
          { 
           var prop = item.GetType() 
            .GetProperty(field, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); 

           var fieldName = prop.Name; 
           var fieldValue = prop.GetValue(item, null); 

           fieldName = GetName(fieldName, propertyFormat); 
           objectToReturn2.Add(new JProperty(fieldName, fieldValue)); 
          } 
          catch (Exception ex) { } 
         }); 

         listOfObjects.Add(objectToReturn2); 
        } 

        return listOfObjects.ConvertAll(o => o); 
       } 
       //==== 

       listOfFields.ForEach(field => 
       { 
        try 
        { 
         var prop = objectToShape.GetType() 
          .GetProperty(field, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); 

         var fieldName = prop.Name; 
         var fieldValue = prop.GetValue(objectToShape, null); 

         fieldName = GetName(fieldName, propertyFormat); 
         objectToReturn.Add(new JProperty(fieldName, fieldValue)); 
        } 
        catch (Exception ex) { } 
       }); 

       return objectToReturn; 
      } 

      return objectToShape; 
     } 

     private static string GetName(string field, PropertyFormat propertyFormat) 
     { 
      switch (propertyFormat) 
      { 
       case PropertyFormat.AsIs: return field; 
       case PropertyFormat.PascalCase: return field.ToPascalCase(); 
       case PropertyFormat.CamelCase: return field.ToCamelCase(); 
       default: return field; 
      } 
     } 
    } 
} 

// Kullanım

[HttpGet, Route("api/someroute")] 
public async Task<IHttpActionResult> YourMethod(string fields = null) 
{ 
    try 
    { 
     var products = await yourRepo.GetProductsList(); 

     if (fields.HasValue()) 
     { 
       return Ok(products.ToDataShape(fields, PropertyFormat.CamelCase)); 
     } 

     return Ok(products); 
    } 
    catch (Exception) 
    { 
     return InternalServerError(); 
    } 
} 

// Çağrı rota

/api/someroute?fields=productID,productName 

// çıkışı (json)

{ 
    productID: 1, 
    productName: "Some Name" 
} 
+0

Ancak zaman ayırdığınız için teşekkürler, bu yöntemle, veriler veritabanından kayıtlar alındıktan sonra bellekte "şekilli" mi? Veritabanına doğru sql komutunu gönderen bir çözüm bulmayı umuyorum. –

+0

@KemalEmin şunları deneyebilirsiniz: IQuerable GetAsQuerable() 've' Seç (sütun adlarınız) ' – Eldho

+0

@KemalEmin Sanırım ne yapmaya çalıştığınızı yanlış anladım. Kod tekeri, yorumlarda belirtildiği gibi sadece kullanabilirsiniz. (Bir queriable olarak), ancak istediğiniz nesne türü olarak geri dönmeyeceksin (tüm diğer alanların boş olmasını istemediğiniz sürece). –

İlgili konular