2013-06-06 3 views
13

के लिए एएसपी.NET वेबएपी ओडाटा समर्थन मेरे पास प्रोजेक्ट इकाई और प्रोजेक्ट डीटीओ है। मैं एक वेबएपीआई नियंत्रक विधि बनाने की कोशिश कर रहा हूं जो प्रोजेक्ट डीटीओ को ले और वापस कर सकता है और इसे ओडाटा का समर्थन कर सकता है।डीएसओ

समस्या यह है कि मैं ओआरएम का उपयोग कर रहा हूं जो परियोजना इकाई का उपयोग कर डेटाबेस से क्वेरी कर सकता है प्रोजेक्ट डीटीओ नहीं। क्या कोई तरीका है कि मैं प्रोजेक्ट इकाई क्वेरी पर प्रोजेक्ट डीटीओ के आधार पर ओडाटा से फ़िल्टरिंग/सॉर्टिंग/पेजिंग लागू कर सकता हूं?

public object GetProjects(ODataQueryOptions<Project> query) 
    { 
     var context = new ORM_Context(); 

     var projects = query.ApplyTo(context.Projects); 
     var projectDTOs = projects.Select(
       x => 
       new ProjectDTO 
        { 
         Id = x.Id, 
         Name = x.Name 
        }); 

     return new 
     { 
      TotalCount = Request.GetInlineCount(), //before paging 
      Results = projectDTOs.ToList() 
     }; 
    } 

जाहिर है यहां सबसे महत्वपूर्ण बात यह सही पारित करने के लिए है:

public ODataQueryResult<ProjectDTO> GetProjects(ODataQueryOptions<ProjectDTO> query) 
{ 
    var context = new ORM_Context(); 

    var projects = context.Projects; // IQueryable<Project> 
    var projectDtos = query.ApplyTo(projectDTOs)); // <-- I want to achieve something similar here 
    var projectDTOs = 
     projects.Select(
      x => 
      new ProjectDTO 
       { 
        Id = x.Id, 
        Name = x.Name 
       }); 

    var projectsQueriedList = projectDtos.ToList(); 

    var result = new ODataQueryResult<ProjectDTO>(projectsQueriedList, totalCount); 

    return result; 
} 
+0

आपने क्या किया? – mayu

उत्तर

4

कुछ की तरह इस

using(var dataContext = new ORM_Context()) 
{ 
    var projects = dataContext.Projects; // IQueryable<Project> 

    //Create a set of ODataQueryOptions for the internal class 
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); 
    modelBuilder.EntitySet<Project>("Project"); 
    var context = new ODataQueryContext(
     modelBuilder.GetEdmModel(), typeof(Project)); 
    var newOptions = new ODataQueryOptions<Project>(context, Request); 

    var t = new ODataValidationSettings() { MaxTop = 25 }; 
    var s = new ODataQuerySettings() { PageSize = 25 }; 
    newOptions.Validate(t); 
    IEnumerable<Project> internalResults = 
     (IEnumerable<Project>)newOptions.ApplyTo(projects, s); 

    int skip = newOptions.Skip == null ? 0 : newOptions.Skip.Value; 
    int take = newOptions.Top == null ? 25 : newOptions.Top.Value; 

    var projectDTOs = 
      internalResults.Skip(skip).Take(take).Select(x => 
       new ProjectDTO 
        { 
         Id = x.Id, 
         Name = x.Name 
        }); 

    var projectsQueriedList = projectDtos.ToList(); 
    var result = new ODataQueryResult<ProjectDTO>(
     projectsQueriedList, totalCount); 
    return result; 
} 
+1

आपके उत्तर के लिए बहुत बहुत धन्यवाद! यह पहली नजर में बहुत ही आशाजनक दिखता है। मैं इस समाधान का परीक्षण करूंगा और आशा करता हूं कि यह काम करने जा रहा है। – kubal5003

+0

लगभग सही, मेरे लिए एक मामूली परिवर्तन के साथ शानदार ढंग से काम किया, ODataQueryResult अब अस्तित्व में नहीं है इसलिए मैंने एक IQueryable लौटा दिया। इसमें वस्तुओं की कुल गिनती नहीं है, इसलिए पेजिंग के लिए शानदार नहीं है जो शर्म की बात है लेकिन इसमें अगले पृष्ठ का लिंक शामिल है। – BenCr

+0

@BenCr अब एक 'पेजरसेट <>' कक्षा है http://msdn.microsoft.com/en-us/library/jj890608(v=vs.111).aspx – qujck

0

इस प्रयास करें (मैं इसे संकलित करने के लिए प्रयास नहीं किया है) ODataQueryOptions < पर टाइप करें> और फिर यह अपने जादू को ठीक करता है। ऐसा इसलिए है क्योंकि यह आपके संग्रह/डीबी संदर्भ से पूछने के लिए उस विशेष प्रकार का उपयोग करता है, इसलिए इसे उस प्रकार का होना चाहिए जो वास्तव में संग्रह/संदर्भ में संग्रहीत होता है, जिसे आप वापस करने का प्रयास कर रहे हैं।

जाहिर है, आपके डीटीओ को आपके ओआरएम ऑब्जेक्ट्स (और वे आपके स्निपेट में करते हैं) के साथ मिलकर मिलते हैं या यह उपयोगकर्ता के/ग्राहक के परिप्रेक्ष्य से बहुत अच्छी तरह से काम नहीं करेगा।

मैंने उपर्युक्त कोड संकलित करने का प्रयास नहीं किया क्योंकि मेरे पास आपकी कक्षाएं और अन्य बुनियादी ढांचे नहीं हैं लेकिन यह विचार व्यक्त करने के लिए पर्याप्त होना चाहिए।

2

मुझे लगता है कि ऐसा करने का सबसे आसान तरीका ऑटोमैपर का उपयोग कर है। तो, अपने डीटीओ

[DataContract(Name = "Products")] 
    public class ProductDTO 
    { 
     [Key] 
     [DataMember] 
     public string MyProductMember1 { get; set; } 

     [DataMember] 
     public string MyProductMember2 { get; set; } 
     ... 
    } 

के लिए आप AutoMapper विन्यास में कहीं लिखना चाहिए:

Mapper.CreateMap<Product, ProductDTO>(); 

और कहीं OData के लिए IEdmModel के निर्माण में:

builder.EntitySet<ProductDTO>("Products"); 

और अपने नियंत्रक के लिए कोड दिखेगा जैसे

public class ProductsController : ODataController 
{ 
    [EnableQuery] 
    public IHttpActionResult Get() 
    { 
     var products = context.Products; // IQueryable<Product> 
     return Ok(products.Project().To<ProductDTO>()); 
    } 
} 

इस तरह आपको सीधे अपनी ओआरएम इकाइयों का पर्दाफाश करने की आवश्यकता नहीं है, और फ़िल्टरिंग, पेजिंग, गिनती और यहां तक ​​कि नेस्टेड संग्रहों का विस्तार करने के लिए ओडाटा का उपयोग भी कर सकते हैं, और ईएफ के लिए यह तालिका का उपयोग करके संबंधित एसक्यूएल अनुरोधों में अनुवाद करेगा जिसमें उत्पाद मैप किया गया है । लेकिन सावधान रहें: अधिक जटिल मामलों के लिए (उदाहरण के लिए नेस्टेड संग्रह) इसके परिणामस्वरूप गैर-इष्टतम SQL अनुरोध हो सकता है।