我有以下模型类: -
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());
那么为什么我必须将其转换为列表?
答案 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>
接口。