none
Casting anonymous list to custom typed list RRS feed

  • Question

  • Hi!

    I have a question about casting anonymous list generated by linq query to custom (but compatible) typed list - without using foreach loop. Simple example is as follows...

    I have table Status in database:

    Table Status
    ID int PK
    Desc nvarchar
    ...
    <some other attributes>
    ...

    I have StatusInfo business object in my application's BLL:

    public class StatusInfo
    {
        public int? ID { get; set; }
        public string Desc { get; set; }
    }

    I'd like to get content of Status table using Linq to SQL, and select ID and Desc attributes only. So I wrote the following method (line numbers are for reference only):

    01 public List<StatusInfo> Select(int? id, string desc)
    02 {
    03    List<StatusInfo> statusInfoLST = null;
    04    using (ExampleDataContext db = DbHelper.GetExampleDataContext())
    05    {
    06        var resultSet = (
    07            from r in db.Status
    08            where
    09               (r.ID == id || id == null) &&
    10               (r.Desc == desc || desc == null)
    11            select new
    12            {
    13                r.ID,
    14                r.Desc
    15           }
    16        ).ToList();
    17        statusInfoLST = (List<StatusInfo>)resultSet; // THIS I'd like to accomplish!
    18    }
    19    return statusInfoLST;
    20 }

    I'd like to accomplish something like written in ine 17. I tried to do that with different combinations of Cast and OfType methods in lines 07 (from r in db.Status.Cast<StatusInfo>(), for example) and 16, but without success. Errors were:
    • Unable to cast object of type...
    • No coercion operator is defined between types...
    These errors are somewhat similar to those described in this thread. Answers to this guy's problem are such that I might conclude that there's no way of accomplishing goal in line 17, at least not "out of the box", with simple casting and without foreach loop. My expirience with some OR mappers like few years ago also suggests that. So my questions are as follows:
    1. Well, is there really no simple way of doing such casting?
    2. If answer to question 1 is affirmative then what's the best practice for handling such situations? Defining view in database with only needed columns and mapping such view? Foreach looping?


    Monday, December 1, 2008 1:22 PM

Answers

  • Two alternatives:

     

    1) Select directly into a StatusInfo, and then call .ToList<StatusInfo>():

    11            select new StatusInfo
    12            {
    13                r.ID,
    14                r.Desc
    15           }

     

    or...

     

    2) If your actual usage is more complex than in your example above (i.e. you really want to get a generic list from an anonymous type), see Matt Warren's reply in this thread:

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2666544&SiteID=1#2670101

    Monday, December 1, 2008 4:32 PM
    Answerer
  •  KristoferA wrote:

    Two alternatives:

     

    1) Select directly into a StatusInfo, and then call .ToList<StatusInfo>():

    11            select new StatusInfo
    12            {
    13                r.ID,
    14                r.Desc
    15           }



    Hi!

    Well, didn't exactly work (maybe I was somewhat ambiguous when asking question), but you gave me successful guideline!
    1. I added another constructor to StatusInfo class: public StatusInfo(int? id, string desc)
    2. Then I somewhat modified your code quoted here: 11 select new StatusInfo(r.ID, r.Desc), and converted resultSet to list and simply joined it to statusInfoLST. And it worked, even without further casting!
    So, to summarize, code is as follows:

    public class StatusInfo
    {
    public StatusInfo(int? id, string opis)
    {...<ommited for brevity> }

    public int? ID { get; set; }
    public string Desc { get; set; }
    }

    01 public List<StatusInfo> Select(int? id, string desc)
    02 {
    03 List<StatusInfo> statusInfoLST = null;
    04 using (ExampleDataContext db = DbHelper.GetExampleDataContext())
    05 {
    06 var resultSet = (
    07 from r in db.Status
    08 where
    09 (r.ID == id || id == null) &&
    10 (r.Desc == desc || desc == null)
    11 select new StatusInfo(r.ID, r.Desc)
    12 ).ToList();
    13 statusInfoLST = resultSet;
    14 }
    15 return statusInfoLST;
    16 }

    Thanks!
    Monday, December 1, 2008 6:35 PM

All replies

  • Two alternatives:

     

    1) Select directly into a StatusInfo, and then call .ToList<StatusInfo>():

    11            select new StatusInfo
    12            {
    13                r.ID,
    14                r.Desc
    15           }

     

    or...

     

    2) If your actual usage is more complex than in your example above (i.e. you really want to get a generic list from an anonymous type), see Matt Warren's reply in this thread:

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2666544&SiteID=1#2670101

    Monday, December 1, 2008 4:32 PM
    Answerer
  •  KristoferA wrote:

    Two alternatives:

     

    1) Select directly into a StatusInfo, and then call .ToList<StatusInfo>():

    11            select new StatusInfo
    12            {
    13                r.ID,
    14                r.Desc
    15           }



    Hi!

    Well, didn't exactly work (maybe I was somewhat ambiguous when asking question), but you gave me successful guideline!
    1. I added another constructor to StatusInfo class: public StatusInfo(int? id, string desc)
    2. Then I somewhat modified your code quoted here: 11 select new StatusInfo(r.ID, r.Desc), and converted resultSet to list and simply joined it to statusInfoLST. And it worked, even without further casting!
    So, to summarize, code is as follows:

    public class StatusInfo
    {
    public StatusInfo(int? id, string opis)
    {...<ommited for brevity> }

    public int? ID { get; set; }
    public string Desc { get; set; }
    }

    01 public List<StatusInfo> Select(int? id, string desc)
    02 {
    03 List<StatusInfo> statusInfoLST = null;
    04 using (ExampleDataContext db = DbHelper.GetExampleDataContext())
    05 {
    06 var resultSet = (
    07 from r in db.Status
    08 where
    09 (r.ID == id || id == null) &&
    10 (r.Desc == desc || desc == null)
    11 select new StatusInfo(r.ID, r.Desc)
    12 ).ToList();
    13 statusInfoLST = resultSet;
    14 }
    15 return statusInfoLST;
    16 }

    Thanks!
    Monday, December 1, 2008 6:35 PM
  • You would have to add a parameterless constructor for StatusInfo and then execute the  code

    11            select new StatusInfo
    12            {
    13                r.ID,
    14                r.Desc
    15           }

    Monday, January 25, 2010 4:32 PM