Wednesday, March 2, 2011

Linq union on anonymous types

Recently in my project, i was trying to do a LINQ union on two anonymous types. The compiler didn't seem to be happy with it. Here is what i was trying to do:
var query = (from t in taskRepository
                         join s in stepRepository on t.TaskID equals s.ID
                         where t.UserID == 420
                         select new{ID = t.ID,DisplayText = t.DisplayText,ReviewStepID = null
                         })
                       .Union
                       (from rs in reviewStepsRepository
                        where rs.ReviewTypeID == 2
                        select new{ID = null,DisplayText = rs.ReviewName,ReviewStepID = rs.ID
                        })
                       .OrderByDescending(o => o.ID);
With some research, ended up creating a class with ID,DisplayText and ReviewStepID
 public class MyTask
          {
                public int? ID { getset; }
                             public string DisplayText { getset; }
                             public int? ReviewStepID { getset; }
           }
And, the happy LINQ query looked like below:
var query = (from t in taskRepository
                     join s in stepRepository on t.TaskID equals s.ID
                     where t.UserID == 420
                     select new MyTask() { ID = t.ID,                                            
                                          DisplayText = t.DisplayText,
                                          ReviewStepID = null  
                                       }) .Union 
                                         (from rs in reviewStepsRepository
                                          where rs.ReviewTypeID == 2
                                          select new MyTask() { ID = null, 
                                                                DisplayText = rs.ReviewName, 
                                                                ReviewStepID = rs.ID })
                        .OrderByDescending(o=>o.ID); 
Happy LINQ'ING!!!

1 comment:

  1. I think you went about this the long way. The trouble you were having is that your data types don't match up. You can Union two anonymous types, but they have to match exactly and when you do "ReviewStepID = null" in your first query and "ID = null" in your second, you've inadvertently made your anonymous types different in a way that prevents you from doing a union.

    Try this with your original Linq... it's MUCH simpler. Notice the casts to a nullable int:


    var query = (
    from t in taskRepository
    join s in stepRepository on t.TaskID equals s.ID
    where t.UserID == 420
    select new MyTask() {
    ID = (int?)t.ID,
    DisplayText = t.DisplayText,
    ReviewStepID = (int?)null
    }).Union(
    from rs in reviewStepsRepository
    where rs.ReviewTypeID == 2
    select new MyTask() {
    ID = (int?)null,
    DisplayText = rs.ReviewName,
    ReviewStepID = (int?)rs.ID }
    ).OrderByDescending(o=>o.ID);

    ReplyDelete