我正在使用VS2010和EF4.0。目标是选择任何IEnumerable的字段,以便在DataGridView中显示。以 Northwind.Employees 为例,以下代码没问题。
private void button1_Click(object sender, EventArgs e)
{
NorthwindEntities en = new NorthwindEntities();
dataGridView1.DataSource = SelectNew(en.Employees, new string[] { "EmployeeID", "FirstName" });
}
public object SelectNew(object items, string[] fields)
{
IEnumerable<Employee> ems = items as IEnumerable<Employee>;
return ems.Select(em => new
{
id = em.EmployeeID,
name = em.FirstName
}
).ToArray();
}
参数对象项是 EntityObject的IEnumerable ,该函数将在客户端存储器中执行,现在与数据库无关。
但我在运行时之前不知道EntityObject类型(Employee),因此可能会使用一些复杂的反射。
我查了this,
但是当我将结果绑定到控件时,它只显示没有任何列或数据的空行。并且功能
答案 0 :(得分:1)
我修改了上面评论中指出的例子。这实际上返回IEnumerable<Dictionary<string,object>>
,其中每个Dictionary代表一个“新对象”,字典中的每个键值对代表一个属性及其值。也许您可以修改它以供您使用?
我不确定你是否可以简单地将结果绑定到DataGrid,但你应该能够弄明白。
我不相信可以动态创建匿名类型......但是可以将其更改为使用动态类型,如ExpandoObject
而不是词典。有关如何执行此操作的一些提示,请参阅this question。我从来没有使用动态物体,所以你自己就在那里!
public class TestClassA {
public string SomeString { get; set; }
public int SomeInt { get; set; }
public TestClassB ClassB { get; set; }
}
public class TestClassB {
public string AnotherString { get; set; }
}
public class Program {
private static void Main(string[] args) {
var items = new List<TestClassA>();
for (int i = 0; i < 9; i++) {
items.Add(new TestClassA {
SomeString = string.Format("This is outer string {0}", i),
SomeInt = i,
ClassB = new TestClassB { AnotherString = string.Format("This is inner string {0}", i) }
});
}
var newEnumerable = SelectNew(items, new string[] { "ClassB.AnotherString" });
foreach (var dict in newEnumerable) {
foreach (var key in dict.Keys)
Console.WriteLine("{0}: {1}", key, dict[key]);
}
Console.ReadLine();
}
public static IEnumerable<Dictionary<string, object>> SelectNew<T>(IEnumerable<T> items, string[] fields) {
var newItems = new List<Dictionary<string, object>>();
foreach (var item in items) {
var dict = new Dictionary<string, object>();
foreach (var field in fields)
dict[field] = GetPropertyValue(field, item);
newItems.Add(dict);
}
return newItems;
}
private static object GetPropertyValue(string property, object o) {
if (property == null)
throw new ArgumentNullException("property");
if (o == null)
throw new ArgumentNullException("o");
Type type = o.GetType();
string[] propPath = property.Split('.');
var propInfo = type.GetProperty(propPath[0]);
if (propInfo == null)
throw new Exception(String.Format("Could not find property '{0}' on type {1}.", propPath[0], type.FullName));
object value = propInfo.GetValue(o, null);
if (propPath.Length > 1)
return GetPropertyValue(string.Join(".", propPath, 1, propPath.Length - 1), value);
else
return value;
}
}