生成的LINQ类的动态属性访问

时间:2009-01-15 11:28:45

标签: c# asp.net-mvc linq

如何从生成的LINQ类中访问动态属性?

因为我希望能够自定义显示的表列 其中Partner是从SQL Server数据库表生成的LINQ类。

<table class="grid">
  <thead>
   <tr>
     <% foreach (Column c in (IEnumerable)ViewData["columns"]) { %>
     <th><%= c.Title %></th>    
     <% } %>                               
   </tr>
 </thead>
 <tbody>
 <% foreach (Partner p in (IEnumerable)ViewData.Model) { %>
   <tr>
     <% foreach (Column c in (IEnumerable)ViewData["columns"]) { %>
?????   <th> <%= p.GetProperty(c.Name) %>  </th>  ?????
     <% } %>         
   </tr>       
 <% } %>
  </tbody>
</table>

知道p.GetProperty(c.Name)方法的代码怎么样?

请原谅我,如果问题非常简单,但因为我是C#和LINQ的新手,我真的 无法理解。

4 个答案:

答案 0 :(得分:4)

反思应该提供你想要的东西 - 特别是

typeof(Partner).GetProperty(c.Name).GetValue(p, null)

但是,您可能希望在循环之前执行

var columns = (IEnumerable<string>)ViewData["columns"];
var cols = columns.Select(colName =>
      typeof(Partner).GetProperty(colName)).ToList();

这为您提供了一组可重复使用的PropertyInfo实例,您可以在每行使用这些实例:

 foreach (var col in cols) { %>
     <th><%= col.GetValue(p,null) %></th>
 <% }

(顺便说一下<th/>应该是<td/>吗?)

这应该比重复查找每个属性更有效。有other ways of doing this too(再次更快)。

答案 1 :(得分:2)

我相信以下内容将实现您的目标:

p.GetType().GetProperty(c.Name).GetValue(p)

答案 2 :(得分:1)

反射在这里非常适合,但实际上 - 在编译时一切都是已知的。因此,可以在设计时指定所有内容。

public class DataItem
{
  string Title {get;set;}
  object Value {get;set;}
}

public interface IDataItems
{
  IEnumerable<DataItem> Items()
}


//suppose LINQ gives you this:
public partial class Customer
{
  public string Name {get;set;}
  public string Address {get;set;}
  public int Age {get;set;}
}

//then you add this in another file.
//if there's a lot of this, it can be code genned by design-time reflection
public partial class Customer : IDataItems
{
  public IEnumerable<DataItem> IDataItems.Items()
  {
    yield return new DataItem() {"Name", Name};
    yield return new DataItem() {"Address", Address};
    yield return new DataItem() {"Age", Age};
  }
}

//and the foreach loops look like this:
foreach(DataItem d in ViewData.OfType<IDataItems>().First().Items())
{
  d.Title;
}

foreach(IDataItems container in ViewData.OfType<IDataItems>())
{
    foreach(DataItem d in container.Items())
    {
       d.Value;
    }
}

答案 3 :(得分:0)

没有。这些不是答案。我刚发现它!

这家伙通过投射匿名类型使用示例动态类型。 Linq不需要类定义或特殊扩展方法!这真是太酷了。

http://kirillosenkov.blogspot.com/2008/01/how-to-create-generic-list-of-anonymous.html

这是为匿名类型动态搜索开辟了一些很好的可能性之一。

var anonymousTypeExample = new { startYear = 2000, endYear = 2000, model = "test" };
var list = (new[] { anonymousTypeExample }).ToList();

list.Clear();

list.Add(new{
    startYear = 1990,
    endYear = 2004,
    model = "Honda"
});
list.Add(new
{
    startYear = 1989,
    endYear = 1989,
    model = "KTM"
});
list.Add(new
{
    startYear = 1989,
    endYear = 1989,
    model = "KTM"
});

list = list.OrderBy(l => l.startYear).ToList();

foreach(var l in list)
{
    <div>@l.model @l.startYear - @l.endYear</div>
}