我有一个类,使用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();
如果要将结果序列从一个方法返回到另一个方法,请继续定义适当的类型。
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 */) {
当您需要在代码中的其他地方迭代序列时,这将使您在编译时访问属性。匿名类型很有用,但是当您开始传递它们时,是时候将它们转换为已定义的类型了。
您有2个选择:您可以获得枚举数或迭代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
您正在返回一个匿名类型,但它被强制转换为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")