如何在下面的DoIt函数中获取查询中的一个新属性的值?
public object GetData()
{
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
// this code doesn't work
public void DoIt()
{
var result = GetData();
string shortName = result.ShortName;
}
谢谢!
答案 0 :(得分:4)
匿名类型不会被称为匿名类型。所以:
定义一个带有名称的类型(另外6行代码):
public class Foo
{
public string ShortName { get; set; }
public int SCount { get; set; }
public string DisplayText { get; set; }
}
现在将GetData
签名修改为(0行代码):
public IEnumerable<Foo> GetData()
你的LINQ查询(3个额外的字符,或者如果你选择更有意义的名字,还有几个字符):
var query =
from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Foo
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
答案 1 :(得分:2)
您将返回一个匿名类型(通过select new {}),该类型仅在本地范围内有效。您需要创建一个具体类型并从函数而不是对象返回它。
public SomeClass GetData()
{
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new SomeClass
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
// this code doesn't work
public void DoIt()
{
var result = GetData();
string shortName = result.ShortName;
}
public class SomeClass
{
public string ShortName { get; set; }
public int SCount { get; set; }
public string DisplayText { get; set; }
}
答案 2 :(得分:1)
好吧,DoIt
不知道result
有一个名为ShortName
的属性,因为它的类型为object
。您可以创建一个包含结果,使用反射或使用dynamic
的具体类。请注意,无论哪种方式,GetData
实际上都返回IEnumerable<T>
,其中T
目前是匿名类型。
使用具体类:
public class Foo {
public string ShortName { get; set; }
public int SCount { get; set; }
public string DisplayText { get; set; }
}
public IEnumerable<Foo> GetData() {
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Foo
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
public void DoIt() {
var result = GetData();
foreach(var item in result) {
Console.WriteLine(item.ShortName);
}
}
使用反射:
public IEnumerable GetData() {
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Foo
{
ShortName = grouping.Key,
SCount = grouping.Sum( count => count.Field<int>("ProfCount")),
DisplayText = string.Empty
};
return query;
}
public void DoIt() {
var result = GetData();
PropertyInfo property = result.First().GetType().GetProperty("ShortName");
foreach(var item in result) {
string shortName = property.GetValue(item, null);
Console.WriteLine(shortName);
}
}
答案 3 :(得分:0)
你不能不使用反射。由于它是匿名类型,因此您无法在DoIt()
方法中转换它,因为在编译时不知道类型名称。
答案 4 :(得分:0)
这给了我所需要的东西:
public object GetData()
{
var table = GetDataTable();
var view = table.DefaultView;
//..... more code
var query = from row in view.ToTable().AsEnumerable()
group row by row.Field<string>("ShortName") into grouping
select new Object[]
{
grouping.Key,
grouping.Sum( count => count.Field<int>("ProfCount")),
string.Empty
};
return query;
}
public void DoIt()
{
// Note: Pretend that GetData returned only one result
object[] result = GetData() as object[];
var shortName = result[0];
}