Alex
Alex

Reputation: 35801

Linq AddRange() for objects derived from interface

I'm trying to get results using LINQ in WPF on Visual Studio 2015 using Entity Framework 6 (EF). The results need to appear in one ListView for the employee's tests. I have two EF entities: DrugTests and AlcoholTests. In my project, I have some view models to map these to: DrugTestViewModel and AlcoholTestViewModel, both derived from the interface ITestViewModel.

The two VMs share many properties while also having their own unique ones (hence the need for two entities). I'm using LINQ to return a Task<ObservableCollection<ITestViewModel>>, first fetching from the DrugTests entity:

var query = (from dt in context.DrugTests 
            .Where(x => x.employeeID.Equals(employeeId))
            select new DrugTestViewModel
            {
                EmployeeId = dt.employeeID,
                TestType = "Drug",
                OrderedDate = dt.orderedDate,
                // set other properties
            } 
).ToList();

Then I try to add to the query using this:

query.AddRange(from at in context.AlcoholTests
                   .Where(x => x.employeeID.Equals(employeeId))
               select new AlcoholTestViewModel
               {
                   EmployeeId = at.employeeID,
                   TestType = "Alcohol",
                   // set other properties...
               }
    );

It gives the following exception on the AddRange():

Argument 1: cannot convert from 'System.Linq.IQueryable<MySolution.ViewModel.AlcoholTestViewModel>' to 'System.Collections.Generic.IEnumerable<MySolution.ViewModel.DrugTestViewModel>'

What am I doing wrong?

Upvotes: 3

Views: 1109

Answers (3)

ocuenca
ocuenca

Reputation: 39326

A little late but I would like to share this another solution. I would use Concat this way:

var query=...
var query2=..
var result= query.AsEnumerable<ITestViewModel>().Concat(query2);

This way you maintain deferred execution in case you don't need to materialize the result yet.

Upvotes: 2

Ivan Stoev
Ivan Stoev

Reputation: 205569

The problem is that the query variable type is List<DrugTestViewModel> while you need it to be of type List<ITestViewModel>. Since IQueryable<T> is covariant, you can achieve that by simply specifying explicitly the desired type when calling ToList like this

var query = (...).ToList<ITestViewModel>();

Upvotes: 1

robaudas
robaudas

Reputation: 1638

The from at in context... is a query hence the IQuerable error Adding .ToList() call ad the end of your linq query returns a list that supports IEnumerable.

Your first code snippet contains the .ToList() your second is missing.

Upvotes: 0

Related Questions