【问题标题】:IEnumerable<> to IList<>IEnumerable<> 到 IList<>
【发布时间】:2010-04-28 09:00:19
【问题描述】:

我正在使用 Linq 查询我的数据库并返回一个通用的 IList。

无论我尝试什么,我都无法将 IQueryable 转换为 IList。

这是我的代码。

我不能写得比这更简单,我不明白为什么它不起作用。

public  IList<IRegion> GetRegionList(string countryCode)
{
    var query = from c in Database.RegionDataSource
                where (c.CountryCode == countryCode)
                orderby c.Name
               select new {c.RegionCode, c.RegionName}; 

     return query.Cast<IRegion>().ToList(); 
}

这会返回一个包含正确数量的项目的列表,但它们都是空的 请帮忙,我已经被这个困扰了几天了

【问题讨论】:

  • 这个问题和答案确实说明了鸭子类型的问题,以及 C#/Linq 限制

标签: c# linq ienumerable


【解决方案1】:

您的select 语句返回匿名类型:new {c.RegionCode, c.RegionName}

这不能转换为 IRegion - 这基本上是 Duck 类型,C# 不支持。

您的 linq 语句应该返回一个实现 IRegion 的类型 - 然后您的代码应该可以工作。

但是它不应该运行 - Cast&lt;IRegion&gt; 应该抛出运行时异常。

基本上:

// this isn't anonymous, and should cast
public class MyRegion : IRegion {
    public string RegionCode {get;set;}
    public string RegionName {get;set;}
}

public  IList<IRegion> GetRegionList(string countryCode)
{
    var query = from c in Database.RegionDataSource
                where (c.CountryCode == countryCode)
                orderby c.Name
               select new MyRegion {RegionCode = c.RegionCode, RegionName = c.RegionName}; 

     return query.Cast<IRegion>().ToList(); 
}

更新

如果底层的 Linq 类型实现了IRegion,这会简单很多:

public  IList<IRegion> GetRegionList(string countryCode)
{
    var query = 
        from region in Database.RegionDataSource
        where region.CountryCode == countryCode
        orderby region.Name
        select region; 

     return query.ToList(); 
}

【讨论】:

  • 现在您正在投影到具体类型,因此您不应该需要 Cast&lt;IRegion&gt;()
  • @cottsak:是的,他会的——IList&lt;T&gt; 是不变的。
  • 我有我的 Linq 自动生成的类 Region,它实现了 IRegion。当我使用它时,我收到另一个错误消息 Explicit construction of entity type 'xxxx.LinqToSql.xxxx.Region' in query is not allowed.
  • @nachid - 啊,我想我们已经解决了! Database.RegionDataSource 返回Region。要解决所有问题,您需要以select c 结尾
【解决方案2】:

我很惊讶它不仅完全失败了 - 你试图将每个结果转换为 IRegion,但你正在生成匿名类型的实例,这肯定不会实现 IRegion

一个实现IRegion的具体类型吗?

【讨论】:

    【解决方案3】:

    IRegion 的转换不起作用。您正在选择不会实现IRegion 的匿名类型。有没有办法创建一个实现 IRegion 的实例?

    【讨论】:

      【解决方案4】:

      也许你需要这样的东西:

      public  IList<IRegion> GetRegionList(string countryCode)
      {
          var query = from c in Database.RegionDataSource
                      where (c.CountryCode == countryCode)
                      orderby c.Name
                      select new Region() 
                          {
                              RegionCode = c.RegionCode, 
                              RegionName = c.RegionName
                          }; 
      
           return query.ToList(); 
      }
      

      【讨论】:

      • 在返回查询之前我需要以某种方式转换为 IRegion 编译器抱怨它无法将 IList 转换为 IList
      【解决方案5】:

      也许你需要这样的东西:

      public  IList<IRegion> GetRegionList(string countryCode) 
      { 
          var query = from c in Database.RegionDataSource 
                      where (c.CountryCode == countryCode) 
                      orderby c.Name 
                      select new Region()  
                          { 
                              RegionCode = c.RegionCode,  
                              RegionName = c.RegionName 
                          };  
      
           return query.ToList();  
      }
      

      【讨论】:

      • 我最终做了这个 public IList GetRegionList(string countryCode) { var query = from c in Database.RegionDataSource where (c.CountryCode == countryCode) orderby c.Name select c;返回查询.Cast().ToList(); } 我很快就会回来告诉你谢谢你的宝贵帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 2015-04-01
      相关资源
      最近更新 更多