2016-08-03 36 views
6

tarafından döndürülen devasa bir verinin okunması Bir Oracle veritabanını sorgulamak için WebAPI'yi oluşturduk. Sorgu büyük olan sonuçları döndürür, bu nedenle bazen OutOfMemoryException'u atar. Web API'sı

öneri

Çağrı kavramını kullanmaktı. İstemci uygulamasının, sonuç kümesinin tamamını almak için API'nin kaç kez çağrılması gerektiğini bilmeyeceğini anlamıyorum. Ayrıca, sayfalama için ayrı bir sınıf oluşturmam gerekiyor mu veya API denetleyicimde çalıştırabilir miyim? Bu benim ilk Web API olduğu gibi

kimse bana bu konuda yardım edebilir. biz sadece veritabanı üzerinde okuma erişimine sahiptir çünkü bunun için saklı yordamlar oluşturma olamaz

public HttpResponseMessage Getdetails([FromUri] string[] id) 
{ 
    string connStr = ConfigurationManager.ConnectionStrings["ProDataConnection"].ConnectionString; 
    using (OracleConnection dbconn = new OracleConnection(connStr)) 
    { 
     var inconditions = id.Distinct().ToArray(); 
     var srtcon = string.Join(",", inconditions); 
     DataSet userDataset = new DataSet(); 
     var strQuery = @"SELECT * from STCD_PRIO_CATEGORY where STPR_STUDY.STD_REF IN(" + srtcon + ")"; 
     using (OracleCommand selectCommand = new OracleCommand(strQuery, dbconn)) 
     { 
       using (OracleDataAdapter adapter = new OracleDataAdapter(selectCommand)) 
      { 
       DataTable selectResults = new DataTable(); 
       adapter.Fill(selectResults); 
       var returnObject = new { data = selectResults }; 
       var response = Request.CreateResponse(HttpStatusCode.OK, returnObject, MediaTypeHeaderValue.Parse("application/json")); 
       ContentDispositionHeaderValue contentDisposition = null; 

       if (ContentDispositionHeaderValue.TryParse("inline; filename=ProvantisStudyData.json", out contentDisposition)) 
       { 
        response.Content.Headers.ContentDisposition = contentDisposition; 
       } 

       return response; 
      } 
     } 
    } 
} 
+3

Kodunuz bir sql enjeksiyon sorunu var. Komut parametrelerinin nasıl kullanılacağını okuyun. – rene

cevap

6

API üzerinden çağrı yatan temel düşünce istemci istedikleri verilerin "sayfası" ve "miktar" geçecek olmasıdır istedikleri kayıtların.

Oradan size Al (vardır LINQ to SQL kullanırsanız

Select all records, but skip ((Page - 1) * amount) of records and take (amount) of records.

etkisiyle sorgu şey yapısı) ve) (yazmak için bu çok daha kolay hale getirmek yöntemleri atla olabilir kod tarafında. SQL'e LINQ kullanmıyorsanız, Oracle'a özgü bir şey bulmanız gerekir. İyi bir API "vatansız" olarak tasarlanmıştır beri

Son Not, bunların önceki/sonraki sayfa sorguları işlerken üzerinde hangi sayfa korumak için müşterinin gereksinimi olacaktır. Tipik olarak, sayfa ve miktar değişkenleri Javascript'te veya gizli değişkenler kadar basit bir şekilde saklanır ve kaç sayfaın kullanılabilir olduğunu hesaplamak için kullanılabilir ve benzeri

Aşağıda, sayfalama yapan bir WebAPI çağrısının temel bir örneği verilmiştir . Sen biraz tüm kayıtları ve LINQ eğer SQL potansiyel şey Oracle özgü alma desteklemek için değiştirmeniz gerekebilir/EF bunu desteklemez:

public IActionResult GetProducts(int? page, int? count) 
     { 
      var takePage = page ?? 1; 
      var takeCount = count ?? DefaultPageRecordCount; 

      var calls = context.Products 
          .Skip((takePage - 1) * takeCount) 
          .Take(takeCount) 
          .ToList(); 

      return Json(calls); 
     } 
+0

Teşekkürler Dillie-O ama müşteri bir kerede tüm kayıt kümesini isterse. Mümkün mü. – user4912134

+0

@ user4912134 - Kullanıcı tüm kayıtları bir kerede istiyorsa, bir null'a rastladığınızda, -99 ya da basit bir sayfa değeri belirttiyse, atla/atla seçeneğini yok saymak için API'nize bir şeyler koyabilirsiniz. varsayılan bir geri dönüş var. –

+0

Teşekkürler Dillie-O seçim beyanımı doğru değiştirmem gerekecek. – user4912134

0
IQueryable<ShowMedicineViewModel> query; 
List<ShowMedicineViewModel> medic = new List<ShowMedicineViewModel>(); 
var medicineInfo = _dbContext.medicine_details.Where(m => (m.Medicine_name.StartsWith(medicinename)) && (m.Medicine_type == medicinetype)).ToList(); 

List<string> TotalMedicine = new List<string>(); 

var results = (medicineInfo.OrderBy(x => x.id) 
       .Skip((pages - 1) * 2) 
       .Take(2)); 


Parallel.ForEach(results, item => 
{ 
    var temp = Mapper.DynamicMap<medicine_details, ShowMedicineViewModel>(item); 

    medic.Add(temp); 
}); 

Dictionary<string, int> dictionary2 = new Dictionary<string, int>(); 
dictionary2.Add("CurrentPage", pages); 
dictionary2.Add("TotalPages", medicineInfo.Count()/2 < 1 ? 1 : medicineInfo.Count()); 

Dictionary<string, object> dictionary = new Dictionary<string, object>(); 
dictionary.Add("Data", medic); 
dictionary.Add("Page", dictionary2); 

return dictionary;