Search code examples
linqlinq-to-entities

How can I combine multiple refactored Select expressions in Linq (to EF or SQL)?


Say I have this view model:

public class SeriesLinkViewModel
{
    public static Expression<Func<Series, SeriesLinkViewModel>> FromSeries =
        s => new SeriesLinkViewModel
        {
            Name = s.Name,
            Slug = s.Slug,
        };

    public string Name { get; set; }
    public string Slug { get; set; }
}

I stuck the projection function in there for convenience, so now I can say something like:

var links = dc.Series.Select(SeriesLinkViewModel.FromSeries);

Awesome. But what do I do if I wanted to add to this query? Say I wanted to also pull a Description column from the table. Normally, I could just do a select new { } and put Description in there, but I can't quite do that because I can only put one projection function in `.Select() .

I was hoping I could do something like this:

q = from s in dc.Series
    select new
    {
        Series = SeriesLinkViewModel.FromSeries.Compile()(s),
        Description = s.Description
    };

But I get an exception:

System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.FieldExpression' to type 'System.Linq.Expressions.LambdaExpression'.

Or could I at least have all these queries done in one round trip somehow? I know TransactionScope works for making changes, but I don't think it causes queries to be done all at once.


Solution

  • Solved it with LinqKit:

    var fs = SeriesLinkViewModel.FromSeries; //needs to be local for some reason
    q = from s in dc.Series.AsExpandable() //enables LinqKit to do its magic
        select new
        {
            Series = fs.Invoke(s), //and voila!
            Description = s.Description
        };