C# 从LINQ查询中获取值

C# 从LINQ查询中获取值,c#,.net,linq,C#,.net,Linq,如何在下面的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.Fi

如何在下面的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;
}
public对象GetData()
{
var table=GetDataTable();
var view=table.DefaultView;
//……更多代码
var query=来自视图中的行。ToTable().AsEnumerable()
按行分组。字段(“ShortName”)分组
选择新的
{
ShortName=grouping.Key,
Scont=grouping.Sum(count=>count.Field(“ProfCount”),
DisplayText=string.Empty
};
返回查询;
}
//这个代码不起作用
公共无效DoIt()
{
var result=GetData();
字符串shortName=result.shortName;
}

谢谢

匿名类型并不是无缘无故地被称为匿名类型。因此:

使用名称定义类型(另外6行代码):

现在将您的
GetData
签名修改为(另外0行代码):

public IEnumerable GetData()
您的LINQ查询将增加3个字符,如果您选择了更有意义的名称,将增加两个字符:

var查询=
来自视图中的行。ToTable().AsEnumerable()
按行分组。字段(“ShortName”)分组
选择新Foo
{
ShortName=grouping.Key,
Scont=grouping.Sum(count=>count.Field(“ProfCount”),
DisplayText=string.Empty
};

如果不使用反射,则无法执行此操作。由于它是一个匿名类型,您也不能在
DoIt()
方法中对其进行强制转换,因为类型名称在编译时是未知的。

好吧,
DoIt
不知道
result
有一个名为
ShortName
的属性,因为它是作为
对象键入的。您可以创建一个包含结果的具体类、使用反射或使用
动态
。请注意,无论哪种方式,
GetData
都返回一个
IEnumerable
,其中
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);
    }
}
公共类Foo{
公共字符串短名称{get;set;}
公共int搜索{get;set;}
公共字符串DisplayText{get;set;}
}
公共IEnumerable GetData(){
var table=GetDataTable();
var view=table.DefaultView;
//……更多代码
var query=来自视图中的行。ToTable().AsEnumerable()
按行分组。字段(“ShortName”)分组
选择新Foo
{
ShortName=grouping.Key,
Scont=grouping.Sum(count=>count.Field(“ProfCount”),
DisplayText=string.Empty
};
返回查询;
}
公共无效DoIt(){
var result=GetData();
foreach(结果中的var项目){
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);
    }
}
public IEnumerable GetData(){
var table=GetDataTable();
var view=table.DefaultView;
//……更多代码
var query=来自视图中的行。ToTable().AsEnumerable()
按行分组。字段(“ShortName”)分组
选择新Foo
{
ShortName=grouping.Key,
Scont=grouping.Sum(count=>count.Field(“ProfCount”),
DisplayText=string.Empty
};
返回查询;
}
公共无效DoIt(){
var result=GetData();
PropertyInfo property=result.First().GetType().GetProperty(“ShortName”);
foreach(结果中的var项目){
string shortName=property.GetValue(项,空);
Console.WriteLine(缩写名);
}
}

您正在返回一个匿名类型(通过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; }
}
public SomeClass GetData()
{
var table=GetDataTable();
var view=table.DefaultView;
//……更多代码
var query=来自视图中的行。ToTable().AsEnumerable()
按行分组。字段(“ShortName”)分组
选择新类
{
ShortName=grouping.Key,
Scont=grouping.Sum(count=>count.Field(“ProfCount”),
DisplayText=string.Empty
};
返回查询;
}
//这个代码不起作用
公共无效DoIt()
{
var result=GetData();
字符串shortName=result.shortName;
}
公共类
{
公共字符串短名称{get;set;}
公共int搜索{get;set;}
公共字符串DisplayText{get;set;}
}

这给了我所需要的:

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];
}
public对象GetData()
{
var table=GetDataTable();
var view=table.DefaultView;
//……更多代码
var query=来自视图中的行。ToTable().AsEnumerable()
按行分组。字段(“ShortName”)分组
选择新对象[]
{
分组。键,
grouping.Sum(count=>count.Field(“ProfCount”),
字符串。空
};
返回查询;
}
公共无效DoIt()
{
//注意:假设GetData只返回一个结果
对象[]结果=GetData()作为对象[];
var shortName=结果[0];
}

GetData将返回IEnumerable,而不仅仅是Foo。@Etienne de Martel,明白了。编辑:-)是否可以使用现有类型?我宁愿在这里使用datarow。您完全可以使用现有类型。不能在本地范围外使用匿名类型。您只需要一个公共可见的类型,因为您是从公共方法返回它的。(如果方法是私有的,显式类型可以是私有嵌套类。)@James Kovacs:“你不能使用anony
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);
    }
}
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; }
}
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];
}