Answered by:
C# Convert a LINQ query to a List<>

Question
-
I can load records into UpdateLoan class using method Update1. I was hoping to simplify the code like Update2 , but I keep getting this error.
Instance argument: cannot convert from 'System.Linq.IQueryable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<UpdateLoan>'
What LINQ principal have I missed?
Thanks
private class UpdateLoan { public string Loan_ID { get; set; } } private void Upadate1() { List<UpdateLoan> Loans2Mark = new List<UpdateLoan>(); var qryMk = dc.vu_ssi_GL_Trans_UnPosteds.Select(c => new { c.Loan_ID }); foreach (var ln in qryMk) { UpdateLoan rcd = new UpdateLoan(); rcd.Loan_ID = ln.Loan_ID; Loans2Mark.Add(rcd); } } private void Update2() { List<UpdateLoan> Loans2Mark = new List<UpdateLoan>(); var qryMk = dc.vu_ssi_GL_Trans_UnPosteds.Select(c => new { c.Loan_ID }); Loans2Mark = qryMk.ToList<UpdateLoan>(); }
Answers
-
Your query doesn't contain items that are "UpdateLoan" objects, it contains items that are of an anonymous type. There is no implicit conversion between those two types.
Rather than creating an anonymous type in the `Select` method you simply need to create an instance of UpdateLoan:
List<UpdateLoan> Loans2Mark = dc.vu_ssi_GL_Trans_UnPosteds.Select(c => new UpdateLoan { Loan_ID = c.Loan_ID }) .ToList();
Note that there's no sense in creating a blank list before the query; you're not adding items to that list, you're just throwing it away and assigning a new list to that variable. No sense in doing that. Also, you don't need to provide generic arguments to your `ToList` method in the vast majority of cases (in fact, I'd say you never should, personally). If it's not compiling it means that the sequence really isn't of the correct type. Adding the generic argument to `ToList` just hides that, and it'll fail at runtime. You need to either use a `Cast` to explicitly indicate there is a valid cast, or convert the value (using , for example, `Select`) into something that's of the appropriate type.
- Proposed as answer by Fernando Soto - MCSD Tuesday, November 20, 2012 7:28 PM
- Marked as answer by rossman308 Tuesday, November 20, 2012 7:36 PM
All replies
-
Your query doesn't contain items that are "UpdateLoan" objects, it contains items that are of an anonymous type. There is no implicit conversion between those two types.
Rather than creating an anonymous type in the `Select` method you simply need to create an instance of UpdateLoan:
List<UpdateLoan> Loans2Mark = dc.vu_ssi_GL_Trans_UnPosteds.Select(c => new UpdateLoan { Loan_ID = c.Loan_ID }) .ToList();
Note that there's no sense in creating a blank list before the query; you're not adding items to that list, you're just throwing it away and assigning a new list to that variable. No sense in doing that. Also, you don't need to provide generic arguments to your `ToList` method in the vast majority of cases (in fact, I'd say you never should, personally). If it's not compiling it means that the sequence really isn't of the correct type. Adding the generic argument to `ToList` just hides that, and it'll fail at runtime. You need to either use a `Cast` to explicitly indicate there is a valid cast, or convert the value (using , for example, `Select`) into something that's of the appropriate type.
- Proposed as answer by Fernando Soto - MCSD Tuesday, November 20, 2012 7:28 PM
- Marked as answer by rossman308 Tuesday, November 20, 2012 7:36 PM
-
-
Also, you don't need to provide generic arguments to your `ToList` method in the vast majority of cases (in fact, I'd say you never should, personally). If it's not compiling it means that the sequence really isn't of the correct type. Adding the generic argument to `ToList` just hides that, and it'll fail at runtime. You need to either use a `Cast` to explicitly indicate there is a valid cast, or convert the value (using , for example, `Select`) into something that's of the appropriate type.
Calling ToList won't hide anything. SomeEnum.ToList<T>() will compile only if SomeEnum is convertible to IEnumerable<T>; that is, if SomeEnum's items are of type T or derived from T, or implement T. It will not fail at runtime.
Calling Cast, on the other hand, will compile without warning and will fail at runtime if the items are not convertible.
-
Calling ToList won't hide anything. SomeEnum.ToList<T>() will compile only if SomeEnum is convertible to IEnumerable<T>; that is, if SomeEnum's items are of type T or derived from T, or implement T. It will not fail at runtime.
Calling Cast, on the other hand, will compile without warning and will fail at runtime if the items are not convertible.
-
I would use Cast in only one case: if I have a non-generic IEnumerable.
That's the equivalent of specifying the type in a query:
from SomeType x in myEnum
is translated as
myEnum.Cast<SomeType>()
I would use ToList with a type parameter any time I want a list of a base class or interface.
- Edited by Louis.fr Wednesday, November 21, 2012 5:07 PM
-
I agree, except if you're willing to do something like myEnum.OfType<SomeOtherType>.Cast<SomeType>
That way you're only applying that Cast to the objects that you know are able to be casted. Of course this could lead to other problems but I'm just pointing out that if you really need to use Case on a generic you can so long as you make sure it's of the type(s) you're expecting.