Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use an extension method in Entity Framework SubQuery?

I'm trying to consolidate logic for accessing different tables using Entity Framework. I created an extension method for pulling all registrations from my registration entity where the person is attending:

public static IEnumerable<Registration> Attending(this IEnumerable<Registration> registrations)
{
    return registrations.Where(r => r.Status == RegistrationStatus.Paid || r.Status == RegistrationStatus.Assigned || r.Status == RegistrationStatus.Completed);
}

This works great for queries like this:

var attendees = db.Registrations.Attending().ToList();

But it doesn't work when used in a subquery:

ProductTotals = db.Products.Where(p => p.EventID == ev.Id).Select(p => new ProductSummaryViewModel
{
    ProductID = p.ProductID,
    ProductName = p.Name,
    Registrations = p.Registrations.Attending().Count(),
}).ToList();

I get the following error:

LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable1[Registration] Attending(System.Collections.Generic.IEnumerable1[Registration])' method, and this method cannot be translated into a store expression.

Is there any way re-use that code in a subquery?

like image 652
Austin Avatar asked Sep 02 '14 13:09

Austin


People also ask

When should we use extension methods in C#?

In C#, the extension method concept allows you to add new methods in the existing class or in the structure without modifying the source code of the original type and you do not require any kind of special permission from the original type and there is no need to re-compile the original type.

Should you use extension methods?

Extension methods are an excellent addition to the C# language. They enable us to write nicer, more readable code. They allow for more functionally styled programming, which is very much needed in an object-oriented language. They also should be used with care.

What are extension methods and where can we use them?

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.


1 Answers

The main thing you're trying to achieve is reusing the predicate that defines the meaning of Attending. You can do that by storing the expression in a readonly variable that is available to whoever needs it in your application, for example in a static class ExpressionConstants.

public static readonly Expression<Func<Registration, bool>> IsAttending = 
    r => r.Status == RegistrationStatus.Paid
      || r.Status == RegistrationStatus.Assigned
      || r.Status == RegistrationStatus.Completed;

Then you can do

var attendees = db.Registrations.Where(ExpressionConstants.IsAttending).ToList();

And used in the subquery:

ProductTotals = db.Products.Where(p => p.EventID == ev.Id).Select(p => new ProductSummaryViewModel
{
    ProductID = p.ProductID,
    ProductName = p.Name,
    Registrations = p.Registrations.AsQueryable() // AsQueryable()
                     .Where(ExpressionConstants.IsAttending).Count(),
})

The AsQueryable() is necessary because p.Registrations probably is an ICollection.

like image 165
Gert Arnold Avatar answered Oct 11 '22 09:10

Gert Arnold