你如何看待从IEnumerable返回的对象?

时间:2011-12-20 00:41:20

标签: c# asp.net linq-to-sql web-applications foreach

我有一个类,它使用Linq to SQL返回数据库中的区域列表(传递RegionName和RegionID变量)。当我尝试获取其中的数据时会出现问题。我在调试代码时可以看到值(看起来像这样:{RegionID = 1,RegionName =“Asia”})。这也是当使用foreach循环查看返回的每个项目/行时。

关于如何打破这些的任何想法,以便我可以获取每个的值?

以下是正在使用的LINQ语句:

return (from r in db.Regions
        join c in db.Countries on r.RegionID equals c.RegionId
        join i in db.Programs on c.CountryID equals i.CountryID
        select new { r.RegionID, r.RegionName })
        .Distinct();

3 个答案:

答案 0 :(得分:4)

如果要将结果序列从一种方法返回到另一种方法,请继续并定义正确的类型。

public class RegionData // or whatever is appropriate
{
     public int RegionID { get; set; }
     public string RegionName { get; set; } 
}

修改您的查询以选择RegionData

 select new RegionData 
 { 
      RegionID = r.RegionID,
      RegionName = r.RegionName 
 }

您的方法应该返回IEnumerable<RegionData>

IEnumerable<RegionData> GetRegionData(/* parameter list */) {

当您需要在代码中的其他位置迭代序列时,这将使您的编译时访问属性。匿名类型很有用,但是当你开始传递它们时,是时候把它们变成一个定义的类型了。

答案 1 :(得分:0)

您有两个选择:您可以获取枚举数或使用foreach进行迭代。您的查询:

   (from r in db.Regions
    join c in db.Countries on r.RegionID equals c.RegionId
    join i in db.Programs on c.CountryID equals i.CountryID
    select new { r.RegionID, r.RegionName })
   .Distinct();

正在创建一个匿名类型,您可以轻松查看,只要您在方法或代码块的范围内这样做。

一旦失去范围,就必须使用反射来查看匿名类型。在该方法的范围内,您可以选择以下选项:

选项1

var query = (from r in db.Regions
             join c in db.Countries on r.RegionID equals c.RegionId
             join i in db.Programs on c.CountryID equals i.CountryID
             select new { r.RegionID, r.RegionName })
            .Distinct();

// get the enumerator
var enumerator = query.GetEnumerator();
enumerator.Reset();

while(enumerator.MoveNext()){
    var obj = enumerator.Current;
    // you can now use the query's anonymous properties
}

选项2

foreach(var obj in query){
    // much easier to access the properties
} 

如果您要超出方法或代码块的范围,请为@AnthonyPeagram建议为这些属性创建一个类。

有关详细信息,请参阅MSDN: GetEnumerator

答案 2 :(得分:0)

您将返回一个匿名类型,但它正在转换为object,阻止直接访问它的使用。

你可以在这里做一些不同的事情。一种是为这种情况创建一种类型:

public struct Region
{
  public int RegionID{get; set;}
  public string RegionName{get; set;} 
}

然后在查询中使用select new Region{r.RegionID, r.RegionName}。这样您就可以返回IEnumerable<Region>IQueryable<Region>

您可以做的另一件事是将对象从枚举转换为dynamic。然后你可以把这些成员叫做后期。

最后,您可以使用基于反射的方法。使用PropertyInfo对象通常比在这里使用它更麻烦,但请注意,这在DataBinder.Eval()的幕后使用,所以如果你使用带有Repeater或类似控件的枚举,那么你的编写的代码可以与DataBinder.Eval(Container.DataItem, "RegionID")

一起使用