user1404577
user1404577

Reputation:

Cannot implicitly convert type 'System.Linq.IQueryable<TMS.Models.CustomAsset>' to 'System.Collections.Generic.ICollection

I have the following model class :-

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

} 

But when i wrote the following method:-

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;  
 }

I got the following exception :

Error 20 Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Collections.Generic.ICollection'. An explicit conversion exists (are you missing a cast?)

So what is causing this error? To overcome this error i just add a .toList() as follows:

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

So why do I have to convert it to a list?

Upvotes: 3

Views: 13501

Answers (3)

James
James

Reputation: 2201

This is because the LINQ Include method returns an object of type ObjectQuery(T) which implements the IQueryable<T> interface whereas your class is expecting an object which implements the ICollection<T> interface. As both these objects cannot be implicitly converted from one to the other you have to explicitly convert the result of the Include method to a List type, which does implement the ICollection<T> interface.

Upvotes: 1

King King
King King

Reputation: 63317

It's because you defined your CustomAssets as ICollection<CustomAsset>, while an IQueryable<T> does not implement any ICollection<T>. You need a result implementing ICollection<CustomAsset>, when you apply ToList(), it will convert to a List<CustomAsset> which in fact implements ICollection<CustomAsset>

Upvotes: 2

Honza Brestan
Honza Brestan

Reputation: 10947

What you have stored in the customerAssets is just a query - a way, how to get the data. It's not the data itself yet, because it's lazily evaluated. ICollection<T> is an interface built for manipulating data collections that you already have. The query does not implement it, so you cannot implicitly convert from IQueryable<T> to the ICollection<T> Calling ToList() is a simple way how to force loading the data into an ICollection<T>, but it also means in your case, that at that place in code (and execution time) the query will get executed and data will be loaded from whatever database you are querying.

Upvotes: 7

Related Questions