2013-02-25 15 views
5

जब एक मॉडल के लिए एक नियंत्रक जोड़ने, उत्पन्न कार्रवाई इसस्वचालित रूप से नियंत्रक कार्रवाई करने के लिए इकाई पारित

public ActionResult Edit(int id = 0) 
{ 
    Entity entity = db.Entities.Find(id); 
    if (entity == null) 
    { 
     return HttpNotFound(); 
    } 
    return View(entity); 
} 

अब मेरे मामले में मैं एक स्ट्रिंग आईडी जो कई में डीबी आईडी को मैप कर सकते हैं लेने के कुछ ऐसी दिखाई देगी तरीके, सही इकाई के पुनर्प्राप्ति के लिए कोड की कई पंक्तियां उत्पन्न करना। प्रतिलिपि & उस कोड को चिपकाने वाली प्रत्येक क्रिया को चिपकाने के लिए जो एक आईडी को पुनर्प्राप्त करने के लिए आईडी लेती है, बहुत ही सुरुचिपूर्ण महसूस करती है।

नियंत्रक के लिए एक निजी समारोह में पुन: प्राप्ति कोड लाना डुप्लिकेट कोड की मात्रा को कम लेकिन मैं अभी भी इस के साथ छोड़ दिया है:

var entity = GetEntityById(id); 
if (entity == null) 
    return HttpNotFound(); 

वहाँ एक विशेषता और पास में देखने को करने के लिए एक रास्ता है कार्रवाई के लिए इकाई? अजगर से आ रहा है, यह आसानी से एक सजावट के साथ हासिल किया जा सकता है। मैं IOperationBehavior को लागू करके डब्ल्यूसीएफ सेवाओं के लिए कुछ ऐसा करने में कामयाब रहा जो अभी भी सीधे-आगे नहीं लगता है। आईडी द्वारा किसी इकाई को पुनर्प्राप्त करने के बाद से आपको अक्सर ऐसा करने की आवश्यकता होती है, मैं उम्मीद करता हूं कि प्रतिलिपि & प्रतिलिपि कोड के अलावा कोई अन्य तरीका होगा।

आदर्श रूप में यह कुछ इस तरह दिखेगा:

[EntityLookup(id => db.Entities.Find(id))] 
public ActionResult Edit(Entity entity) 
{ 
    return View(entity); 
} 

जहां EntityLookup एक मनमाना समारोह मानचित्रण string idEntity पर ले जाता है और या तो HttpNotFound रिटर्न या पैरामीटर के रूप में लिया गया संस्था के साथ कार्रवाई कहता है।

+0

आप Linq में लैम्ब्डा भाव के बारे में विचार किया ?, आप क्या कर सकते हैं ऐसा करें, आपके पास एक अलग डेटा एक्सेस लेयर हो सकती है, जहां आप डेटा पुनर्प्राप्ति कार्यों को लिख सकते हैं और उन्हें क्रिया विधियों (चिंताओं को अलग करने) के अंदर कॉल कर सकते हैं। :), यदि आप प्रत्येक पुनर्प्राप्ति के लिए निजी तरीके करने जा रहे हैं, तो नियंत्रकों के अंदर कोड की कई पंक्तियां होंगी। –

+0

1. आप अभी भी अपनी सत्यापन सीधे 'GetEntityById' में डाल सकते हैं। 2. आप शायद कस्टम मॉडल बाइंडर की तलाश में हैं। –

उत्तर

3

आप एक कस्टम ActionFilter लिख सकते हैं:

public class EntityLookupAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // retrieve the id parameter from the RouteData 
     var id = filterContext.HttpContext.Request.RequestContext.RouteData.Values["id"] as string; 
     if (id == null) 
     { 
      // There was no id present in the request, no need to execute the action 
      filterContext.Result = new HttpNotFoundResult(); 
     } 

     // we've got an id, let's query the database: 
     var entity = db.Entities.Find(id); 
     if (entity == null) 
     { 
      // The entity with the specified id was not found in the database 
      filterContext.Result = new HttpNotFoundResult(); 
     } 

     // We found the entity => we could associate it to the action parameter 

     // let's first get the name of the action parameter whose type matches 
     // the entity type we've just found. There should be one and exactly 
     // one action argument that matches this query, otherwise you have a 
     // problem with your action signature and we'd better fail quickly here 
     string paramName = filterContext 
      .ActionDescriptor 
      .GetParameters() 
      .Single(x => x.ParameterType == entity.GetType()) 
      .ParameterName; 

     // and now let's set its value to the entity 
     filterContext.ActionParameters[paramName] = entity; 
    } 
} 

और उसके बाद:

[EntityLookup] 
public ActionResult Edit(Entity entity) 
{ 
    // if we got that far the entity was found 
    return View(entity); 
} 
+0

मुझे यह दृष्टिकोण पसंद है :) हालांकि, एंटिटी फ्रैमवर्क एक 'System.Data.Entity.DynamicProxies। *' ऑब्जेक्ट को वापस लौटता प्रतीत होता है, इसलिए 'entity.GetType()' तुलना इरादे के अनुसार काम नहीं करती है। – mensi

+0

'entity.GetType()। बेस टाइप 'काम करता है – mensi

0

आप समान कोड दोहरा रहे हैं तो आप एक विस्तार विधि का उपयोग कर सकते हैं।

public static class ControllerExtensions 
{ 
    public static ActionResult StandardEdit<TEntity>(
     this Controller controller, 
     DbContext db, 
     long id) 
     where TEntity : class 
    { 
     TEntity entity = db.Set<TEntity>().Find(id); 
     if (entity == null) 
     { 
      return controller.HttpNotFound(); 
     } 
     return controller.View(entity); 
    } 
} 

public ActionResult Edit(long id = 0) 
{ 
    return this.StandardEdit<Client>(db, id); 
} 

तुम सच में बिल्कुल एक ही कोड कई बार तो इस विरासत के साथ सुलझाया जाना चाहिए दोहरा रहे हैं।

एक आम नियंत्रक कि से Controller

public class StandardController : Controller 
{ 
    public ActionResult Edit<TEntity>(long id = 0) 
     where TEntity : class 
    { 
     TEntity entity = db.Set<TEntity>().Find(id); 
     if (entity == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(entity); 
    } 
} 

विरासत बनाएँ और अपने मॉडल नियंत्रकों को बदलने के लिए इस नए नियंत्रक से प्राप्त करना:

public class ClientController : StandardController 
{ 
    public ActionResult Edit(long id = 0) 
    { 
     return base.Edit<Client>(id); 
    } 
} 
संबंधित मुद्दे