2009-01-03 17 views
6

मैंने इसके बारे में कई प्रश्न देखे हैं, लेकिन मुझे वास्तव में कभी जवाब नहीं मिला है।LINQ बेनामी प्रकार + एमवीसी दृश्य

मैं वेब फॉर्म से एमवीसी तक काफी बड़े वेब एप्लिकेशन को परिवर्तित कर रहा हूं और कुछ समय बाद मुझे डेटा को देखने के लिए समस्या का सामना करना पड़ा।

//This is just an example ViewData["QProducts"] = from p in db.Products select new{Name = p.Name, Date = p.ToShortDateString() } ViewData["QUsers"] = from u in db.Users select u;

मैं इस तरह एक foreach पाश का उपयोग html में वस्तुओं से अधिक पुनरावृति करने के लिए,: लड़ाई में मैं कोड निष्पादित

foreach(var q in (IEnumerable)ViewData["QEvents"]) 
{ 
    /*Print the data here*/ 
} 

का उपयोग कर MVC मैं सिर्फ एक asp:Repeater इस्तेमाल किया से पहले, लेकिन चूंकि यह एमवीसी है मैं एएसपी.NET नियंत्रणों का उपयोग नहीं कर सकता।

मुझे इस डेटा को व्यू में कैसे पास करना है? मेरे पास वास्तव में बेनामी प्रकारों का उपयोग न करने का विकल्प नहीं है। <%#ViewData.Eval()%> स्पष्ट रूप से काम नहीं करेगा।

कोई विचार?

उत्तर

15

बल्कि एक गुमनाम प्रकार की तुलना में, नाम और तारीख धारण करने के लिए एक प्रकार बनाने के

from p in db.Products select new NameDate { Name = p.Name, Date = p.Date } 

जोरदार आपके विचार टाइप MyView<IEnumerable<NameDate>> होने के लिए और तो बस foreach (var nameDate in ViewData.Model)...

+0

एक अच्छा उत्तर के लिए धन्यवाद। – impClaw

+0

आपका स्वागत है - लेकिन खेद है कि मैं जेनेरिक उद्धृत करना भूल गया, इसलिए यह सुगम नहीं है। इसे संपादित करेंगे ... –

+1

तो कोई नई कक्षा बनाने से बचने का कोई तरीका नहीं है? मुझे वास्तव में इस मामले में बेनामी प्रकार पसंद हैं, वे कुछ जेनरेट किए गए क्षेत्र को प्राप्त करने का एक त्वरित और दृढ़ता से टाइप किया गया तरीका है और मुझे केवल 1 विशेष मामले के लिए पूरी नई कक्षा बनाना पसंद नहीं है। अज्ञात प्रकार को देखने के लिए पास करने का कोई साफ तरीका है? – emzero

1

स्पष्ट रूप से एक सूची को बदलने और ViewData कास्टिंग पर विचार करें:

ViewData["QUsers"] = (from u in db.Users select u).ToList(); 

foreach(Users u in (List<Users>)ViewData["QUsers"]){ 

    /*Print the data here*/ 

} 

आप डेटा का विश्लेषण कई तरीकों, ViewData का उपयोग कर पारित कर सकते हैं के रूप में आप से ऊपर हैं, या TempData क्रिया के बीच पारित करने के लिए। आप दृढ़ता से टाइप किए गए मॉडल को रखने के लिए ViewData.Model का भी उपयोग कर सकते हैं। नोट आप दृश्य की परिभाषा को बदलने के लिए करना होगा कि

ViewPage<User> 

एक अच्छा पुनरावर्तक प्रतिस्थापन के लिए के रूप में की तरह कुछ http://www.codeplex.com/MVCContrib कोशिश हो। उनके पास एक ग्रिड एचटीएमएल हेल्पर है जो मदद कर सकता है।

public class NameDate 
{ 
    public string Name { get; set; } 
    public DateTime Date { get; set; } 
} 

फिर उस का उपयोग अपने Linq क्वेरी में:

1

यदि आप केवल एक प्रक्षेपण को प्रदर्शित करने के लिए एक अलग वर्ग बनाने से बचना चाहते हैं, तो आप इसका उपयोग करने का भी सहारा ले सकते हैं एक शब्दकोश है, तो जैसे:

from person in personList select new Dictionary<string, string> 
{ 
    { "Name", person.Firstname + " " + person.Lastname }, 
    { "Id", person.Id.ToString() } 
}; 

फिर आप

ViewPage<IEnumerable<Dictionary<string, string>>> 

करने के लिए अपने viewpage टाइप कर सकते हैं और अंत में इतना की तरह ध्यान में रखते हुए सूची पर पुनरावृति:

<% foreach (Dictionary<string, string> p in (IEnumerable)ViewData.Model) 
{ %> 
    <li> <%=p["Id"] %> - <%= p["Name"] %> </li> 
<% } %> 

कहने की जरूरत नहीं, दोष यह है कि आपका कोड अब "जादू तार" से भरा है, जिससे संकलन समय की जांच की अनुपस्थिति के कारण इसे और अधिक त्रुटि प्रवण कर रही है।

2

यदि आप थोड़ा आलसी महसूस कर रहे हैं, तो आप इस कोड का उपयोग यहां कर सकते हैं ... यह थोड़ा लंबा है, लेकिन मूल रूप से यह प्रतिबिंब के लिए एक रैपर है ...

var something = { Name = "Jim", Age = 25 }; 
AnonymousType type = AnonymousType.Create(something); 

//then used... 
string name = type.Get<string>("Name"); 
int age = type.Get<int>("Age", -1 /* optional default value */); 

और यहाँ कोड है ...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 

namespace Code { 

    /// <summary> 
    /// A convenient method of accessing the values of an 
    /// anonymous type without needing to define a separate class 
    /// </summary> 
    public class AnonymousType { 

     #region Constants 

     private const string EXCEPTION_MISSING_PARAMETER_INFORMATION = 
      "Unable to match the parameter '{0}' to a property in the AnonymousType. This could be due to a casting problem or a Property that does not exist."; 
     private const string EXCEPTION_COULD_NOT_ACCESS_FIELD = 
      "Unable to find a field named '{0}' (of type {1})"; 
     private const string EXCEPTION_COULD_NOT_ACCESS_FIELD_AT_INDEX = 
      "Unable to find a field named '{0}' at the requested index (of type {1})"; 

     #endregion 

     #region Constructors 

     /// <summary> 
     /// Creates a new AutoType for methods that return Anonymus types 
     /// </summary> 
     public AnonymousType(object type) { 
      this._Init(type, false); 
     } 

     /// <summary> 
     /// Creates a new AutoType for methods that return Anonymus types and 
     /// detetrmins if exceptions should be thrown if a type is missing 
     /// </summary> 
     public AnonymousType(object type, bool supressErrors) { 
      this._Init(type, supressErrors); 
     } 

     /// <summary> 
     /// Initalizes the data for the is type 
     /// </summary> 
     private void _Init(object type, bool supressErrors) { 
      this.SupressExceptions = supressErrors; 
      this.m_Type = type.GetType(); 
      this.m_TypeData = type; 
     } 

     #endregion 

     #region Static Routines 

     /// <summary> 
     /// Creates a new Anonymous Type from the provided object data 
     /// </summary> 
     public static AnonymousType Create(object data) { 
      return new AnonymousType(data); 
     } 

     /// <summary> 
     /// Creates a new Anonymous Type from the provided object data 
     /// </summary> 
     public static AnonymousType Create(object data, bool supressErrors) { 
      return new AnonymousType(data, supressErrors); 
     } 

     #endregion 

     #region Private Members 

     /// <summary> 
     /// The type that will be accessed via reflection 
     /// </summary> 
     private Type m_Type; 

     /// <summary> 
     /// The actual typs that is being used 
     /// </summary> 
     private object m_TypeData; 

     #endregion 

     #region Properties 

     /// <summary> 
     /// Determines if errors should be thrown if any casting errors take place 
     /// </summary> 
     public bool SupressExceptions { get; set; } 


     /// <summary> 
     /// Accessess a property by name and returns an object 
     /// </summary> 
     public object this[string property] { 
      get { 
       return this.Get<object>(property); 
      } 
     } 

     #endregion 

     #region Public Methods 

     /// <summary> 
     /// Checks if this Anonymous Type has the specified property 
     /// </summary> 
     public bool Has(string property) { 
      return ((m_Type.GetProperty(property) as PropertyInfo) != null); 
     } 

     /// <summary> 
     /// Returns if this Anonymous type has the specified property and that 
     /// the value matches the type specified 
     /// </summary> 
     public bool Has(string property, Type isType) { 

      //try and get the property 
      PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo; 

      //If this type doesn't exist at all, just return false 
      if (prop == null) { return false; } 

      //if it does exist, verify the type 
      if (prop.PropertyType.Equals(isType)) { return true; } 
      return false; 

     } 

     /// <summary> 
     /// Returns a type value using the specified type 
     /// </summary> 
     public T Get<T>(string property) { 

      //return this value if needed    
      PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo; 
      try { 
       return (T)prop.GetValue(this.m_TypeData, null); 
      } 
      catch (Exception ex) { 
       if (this.SupressExceptions) { return default(T); } 
       throw new Exception(
        string.Format(EXCEPTION_COULD_NOT_ACCESS_FIELD, property, typeof(T).Name), 
        ex 
        ); 
      } 
     } 



     /// <summary> 
     /// Returns a type value using the specified type 
     /// </summary> 
     public T Get<T>(string property, object[] index) { 

      //return this value if needed 
      PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo; 
      try { 
       return (T)prop.GetValue(this.m_TypeData, index); 
      } 
      catch (Exception ex) { 
       if (this.SupressExceptions) { return default(T); } 
       throw new Exception(
        string.Format(EXCEPTION_COULD_NOT_ACCESS_FIELD_AT_INDEX, property, typeof(T).Name), 
        ex 
        ); 
      } 
     } 



     /// <summary> 
     /// Returns a type value using the specified type but includes a default value 
     /// if one it missing 
     /// </summary> 
     public T Get<T>(string property, T defaultValue) { 
      //return this value if needed 
      PropertyInfo prop = m_Type.GetProperty(property) as PropertyInfo; 
      if (prop == null) { return defaultValue; } 
      try { 
       return (T)prop.GetValue(this.m_TypeData, null); 
      } 
      catch (Exception ex) { 
       if (this.SupressExceptions) { return defaultValue; } 
       throw new Exception(
        string.Format(EXCEPTION_COULD_NOT_ACCESS_FIELD, prop, typeof(T).Name), 
        ex 
        ); 
      } 

     } 



     /// <summary> 
     /// Accepts a delegate that will use the names of the passed in 
     /// parameters as properties to map to. If the property does not 
     /// exist, then the method will fail. 
     /// </summary> 
     public void Use<T1>(Action<T1> with) { 

      //set a default for each of the params 
      T1 param1 = default(T1); 

      //get the parameters for this method 
      var paramList = with.Method.GetParameters(); 

      //update each of the parameters    
      string paramName = string.Empty; 
      try { 
       for (int i = 0; i < paramList.Length; i++) { 

        //find the correct matching property for this parameter 
        paramName = paramList[i].Name; 
        switch (i + 1) { 
         case 1: 
          param1 = this.Get<T1>(paramName); 
          break; 
        } 
       } 

      } 
      catch (Exception ex) { 
       throw new ArgumentException(
        string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName), 
        ex 
        ); 
      } 

      //otherwise, execute the method provided 
      with(param1); 

     } 



     /// <summary> 
     /// Accepts a delegate that will use the names of the passed in 
     /// parameters as properties to map to. If the property does not 
     /// exist, then the method will fail. 
     /// </summary> 
     public void Use<T1, T2>(Action<T1, T2> with) { 

      //set a default for each of the params 
      T1 param1 = default(T1); 
      T2 param2 = default(T2); 

      //get the parameters for this method 
      var paramList = with.Method.GetParameters(); 

      //update each of the parameters    
      string paramName = string.Empty; 
      try { 
       for (int i = 0; i < paramList.Length; i++) { 

        //find the correct matching property for this parameter 
        paramName = paramList[i].Name; 
        switch (i + 1) { 
         case 1: 
          param1 = this.Get<T1>(paramName); 
          break; 

         case 2: 
          param2 = this.Get<T2>(paramName); 
          break; 
        } 
       } 

      } 
      catch (Exception ex) { 
       throw new ArgumentException(
        string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName), 
        ex 
        ); 
      } 

      //otherwise, execute the method provided 
      with(param1, param2); 

     } 



     /// <summary> 
     /// Accepts a delegate that will use the names of the passed in 
     /// parameters as properties to map to. If the property does not 
     /// exist, then the method will fail. 
     /// </summary> 
     public void Use<T1, T2, T3>(Action<T1, T2, T3> with) { 

      //set a default for each of the params 
      T1 param1 = default(T1); 
      T2 param2 = default(T2); 
      T3 param3 = default(T3); 

      //get the parameters for this method 
      var paramList = with.Method.GetParameters(); 

      //update each of the parameters    
      string paramName = string.Empty; 
      try { 
       for (int i = 0; i < paramList.Length; i++) { 

        //find the correct matching property for this parameter 
        paramName = paramList[i].Name; 
        switch (i + 1) { 
         case 1: 
          param1 = this.Get<T1>(paramName); 
          break; 

         case 2: 
          param2 = this.Get<T2>(paramName); 
          break; 

         case 3: 
          param3 = this.Get<T3>(paramName); 
          break; 
        } 
       } 

      } 
      catch (Exception ex) { 
       throw new ArgumentException(
        string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName), 
        ex 
        ); 
      } 

      //otherwise, execute the method provided 
      with(param1, param2, param3); 

     } 



     /// <summary> 
     /// Accepts a delegate that will use the names of the passed in 
     /// parameters as properties to map to. If the property does not 
     /// exist, then the method will fail. 
     /// </summary> 
     public void Use<T1, T2, T3, T4>(Action<T1, T2, T3, T4> with) { 

      //set a default for each of the params 
      T1 param1 = default(T1); 
      T2 param2 = default(T2); 
      T3 param3 = default(T3); 
      T4 param4 = default(T4); 

      //get the parameters for this method 
      var paramList = with.Method.GetParameters(); 

      //update each of the parameters    
      string paramName = string.Empty; 
      try { 
       for (int i = 0; i < paramList.Length; i++) { 

        //find the correct matching property for this parameter 
        paramName = paramList[i].Name; 
        switch (i + 1) { 
         case 1: 
          param1 = this.Get<T1>(paramName); 
          break; 

         case 2: 
          param2 = this.Get<T2>(paramName); 
          break; 

         case 3: 
          param3 = this.Get<T3>(paramName); 
          break; 

         case 4: 
          param4 = this.Get<T4>(paramName); 
          break; 
        } 
       } 

      } 
      catch (Exception ex) { 
       throw new ArgumentException(
        string.Format(EXCEPTION_MISSING_PARAMETER_INFORMATION, paramName), 
        ex 
        ); 
      } 

      //otherwise, execute the method provided 
      with(param1, param2, param3, param4); 

     } 

     #endregion 

     #region Working With Arrays 

     /// <summary> 
     /// Returns the specified property as an array of AnonymousTypes 
     /// </summary> 
     public AnonymousType[] AsArray(string property) { 
      object[] values = this.Get<object[]>(property); 
      return values.Select(o => { 
       if (o is AnonymousType) { return (AnonymousType)o; } 
       return new AnonymousType(o); 
      }).ToArray(); 
     } 

     /// <summary> 
     /// Performs the specified action on each value in an array of AnonymousTypes 
     /// </summary> 
     public void WithEach(string property, Action<AnonymousType> action) { 
      foreach (AnonymousType value in this.AsArray(property)) { 
       action(value); 
      } 
     } 

     #endregion 

     #region Static Methods 

     /// <summary> 
     /// Returns the type of data for the provided object 
     /// </summary> 
     public static T Get<T>(object data, string property) { 
      return new AnonymousType(data).Get<T>(property); 
     } 

     /// <summary> 
     /// Returns the type of data for the provided object 
     /// </summary> 
     public static T Get<T>(object data, string property, T defaultValue) { 
      return new AnonymousType(data).Get<T>(property, defaultValue); 
     } 

     /// <summary> 
     /// Returns the type of data for the provided object 
     /// </summary> 
     public static AnonymousType[] AsArray(object data, string property) { 
      return new AnonymousType(data).AsArray(property); 
     } 

     /// <summary> 
     /// Performs the following action on each of the values in the specified 
     /// property value for a user 
     /// </summary> 
     public static void WithEach(object data, string property, Action<AnonymousType> action) { 
      new AnonymousType(data).WithEach(property, action); 
     } 

     #endregion 

    } 
} 
0

तुम सिर्फ MVC से RouteValueDictionary का उपयोग नहीं कर सकते हैं?

संबंधित मुद्दे