динамический доступ к свойствам для сгенерированных классов LINQ - PullRequest
3 голосов
/ 15 января 2009

Как я могу получить динамический доступ к свойствам из сгенерированного класса LINQ?

Причина Я бы хотел иметь возможность настроить отображаемые столбцы таблицы где Partner - это класс LINQ, созданный из таблицы базы данных SQL Server.

<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 ]

4 голосов
/ 15 января 2009

Отражение должно обеспечивать то, что вы хотите - в частности,

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/>?)

Это должно быть немного эффективнее, чем повторное нахождение каждого свойства. Существуют другие способы сделать это тоже (снова быстрее).

2 голосов
/ 15 января 2009

Я верю, что следующее достигнет того, что вы хотите:

p.GetType().GetProperty(c.Name).GetValue(p)
1 голос
/ 15 января 2009

Отражение здесь очень хорошо подходит, но на самом деле - все известно во время компиляции. Таким образом, можно указать все во время разработки.

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;
    }
}
0 голосов
/ 06 сентября 2012

Нет. Это не ответы. Я только что нашел это!

Этот парень использует пример динамической типизации путем приведения анонимных типов. Не требуется определения классов или специальных методов расширения для 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>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...