如何查询匿名类型集合?

时间:2009-12-09 14:18:31

标签: linq linq-to-sql anonymous-types

如何查询使用select new填充/创建的集合?

我有BindingSource

this.bindingSource.DataSource = 
    from row in db.Table
    select new 
    {
      name = row.Name + row.Num.ToString()
    };

我想像查询其他BindingSources一样查询它:

var query = from row in (IEnumerable<Table>)anotherBindingSource.List
            where row.name == "asd"
            select row;

由于bindingSource包含匿名类型,我收到此错误:

  

无法投射类型的对象   “System.Data.Linq.SortableBindingList 1[<>f__AnonymousType8 15   等。等。输入'System.Collections.Generic.IEnumerable`1 [Table]'。

我该怎么办?

1 个答案:

答案 0 :(得分:5)

嗯,不确定你到底想要做什么,但是一个匿名类型!=一个Table对象。该异常表示您正在尝试将匿名类型的IEnum(具有奇怪名称的编译器生成的类)转换为类型为Table的IEnum。

你无法在C#中使用类型。例如,你不能这样做:
(Table)"Lol I'd like to be a table pls kthx"
您不能转换任何不是Table的类型,也不能从Table扩展到表

所以你问的是不可能的。你可能应该退后一步,问一个关于你想要完成什么的更普遍的问题。


关于anon类型的更多内容......它们实际上只在定义它们的方法范围内有意义。看来您可能正在从方法调用返回您的匿名类型枚举,然后尝试排序。这不起作用,因为一旦匿名类型离开方法范围,它被认为(至少通过intellisense)是一个对象,获得其属性的唯一方法是使用反射。

如果您的示例不仅仅是简化版本,您可以完全跳过anon类型......

this.bindingSource.DataSource = 
    from row in db.Table
    select row.Name + row.Num.ToString();

这是一个IEnumerable,可以这样查询:

var query = from row in anotherBindingSource
            where row.StartsWith("asd")
            select row;

然而,看起来你并没有完成任何事情......


您无法在定义它们的范围之外查询匿名类型。

这有效:

public void Worthless(Hurr hurr)
{
  var query = from x in hurr select new { x.Durr };

  var requery = from x in query where x.Durr == "lol" select x;
}

这不是:

public class Anonymous
{
  public IEnumerable GetMyDurrs(Hurr hurr)
  {
    return from x in Hurr select new { x.Durr };
  }

  public IEnumerable WeedMyDurrs(Hurr hurr, string value)
  {
    // this won't compile
    return from x in GetMyDurrs(hurr) where x.Durr == value select x;
  }
}

第二个示例将无法编译,因为匿名类型是在另一个范围内定义的。

实现此功能的唯一方法是定义类型。

public class Anonymous
{
  public IEnumerable<Anonymous.MyDurr> GetMyDurrs(Hurr hurr)
  {
    return from x in Hurr select new MyDurr { Durr = x.Durr };
  }

  public IEnumerable<Anonymous.MyDurr> WeedMyDurrs(Hurr hurr, string value)
  {
    // this won't compile
    return from x in GetMyDurrs(hurr) where x.Durr == value select x;
  }

  public class MyDurr { public string Durr {get;set;} }
}