无法将类型'System.Linq.IQueryable <tms.models.customasset>'隐式转换为'System.Collections.Generic.ICollection </tms.models.customasset>

时间:2013-11-27 11:55:27

标签: c# asp.net-mvc asp.net-mvc-4

我有以下模型类: -

public class CustomerCustomAssetJoin
{
    public CustomAsset CustomAsset  { get; set; }
    public ICollection<CustomAsset> CustomAssets { get; set; }

} 

但是当我写下面的方法时: -

public CustomerCustomAssetJoin CustomerCustomAsset(string customerName)
{
    var customerAssets = tms.CustomAssets.Include(a => a.CustomAssetType).Where(a => a.CustomerName.ToLower() == customerName.ToLower());
    CustomerCustomAssetJoin caj = new CustomerCustomAssetJoin
    {
         CustomAsset = new CustomAsset {CustomerName = customerName },
         CustomAssets = customerAssets
    };
    return caj;  
 }

我遇到以下异常:

  

错误20无法隐式转换类型   'System.Linq.IQueryable'来   '了System.Collections.Generic.ICollection'。一个   存在显式转换(您是否错过了演员?)

那是什么导致了这个错误?为了克服这个错误,我只需添加一个.toList(),如下所示:

var customerAssets = tms.CustomAssets.Include(a => a.CustomAssetType).Where(a => a.CustomerName.ToLower() == customerName.ToLower());

那么为什么我必须将其转换为列表?

3 个答案:

答案 0 :(得分:7)

您在customerAssets中存储的内容只是一种查询 - 一种方式,如何获取数据。这还不是数据本身,因为它被懒惰地评估了。 ICollection<T>是一个用于操作您已拥有的数据集合的接口。查询没有实现它,因此您无法隐式地从IQueryable<T>转换为ICollection<T>调用ToList()是一种如何强制将数据加载到ICollection<T>的简单方法,但是它也意味着在你的情况下,在代码(和执行时间)的那个地方,查询将被执行,数据将从你正在查询的任何数据库加载。

答案 1 :(得分:3)

这是因为您将CustomAssets定义为ICollection<CustomAsset>,而IQueryable<T>未实现任何ICollection<T>。您需要实施ICollection<CustomAsset>的结果,当您应用ToList()时,它会转换为List<CustomAsset>,实际上会实现ICollection<CustomAsset>

答案 2 :(得分:2)

这是因为LINQ Include方法返回类型为ObjectQuery(T)的对象,该对象实现IQueryable<T>接口,而您的类期望实现ICollection<T>接口的对象。由于这两个对象都不能从一个对象隐式转换为另一个,因此必须将Include方法的结果显式转换为List类型,这样做会实现ICollection<T>接口。