Passing parameters to an expression specification using LinqToSQL

I want to reduce duplicate logic in a LinqToSQL query using Expression<Func<T,bool>>. We have successfully completed before using static properties as follows:

public static Expression<Func<Document, bool>> IsActive
{
    get
    {
        return document => !document.Deleted;
    }
}

...

_workspace.GetDataSource<Document>().Where(DocumentSpecifications.IsActive)

However, I'm struggling to get this to work when additional parameters need to be passed to the expression like this:

public static Expression<Func<Comment, bool>> IsUnread(int userId, Viewed viewed)
{
    return
        c =>
        !c.Deleted && c.CreatedByActorID != actorId
        && (viewed == null || c.ItemCreatedDate > viewed.LastViewedDate);
}

...

// Throwing "Argument type 'System.Linq.Expression<X,bool>' is not assignable 
// to parameter type 'System.Func<X,bool>'"
return (from a in alerts
        select
        new UnreadComments
            {
               TotalNumberOfUnreadComments = 
                    a.Comments.Count(CommentSpecifications.IsUnread(actorId, a.LastView))
            })

How do I convert a specification so that it can be adopted in this way and will it be correctly converted to SQL?

EDIT: Following Anders advice, I added .Compile () to the request. Now it works correctly during unit testing in memory collections; however, when LinqToSQL tries to convert it to SQL, I get the following exception:

System.NotSupportedException: , "Count"

:

a.Comments.Count(CommentSpecifications.IsUnread(actorId, a.LastView).Compile())
a.Comments.AsQueryable().Count(CommentSpecifications.IsUnread(actorId, a.LastView))
+3
1

, linq-to-objects, linq-to-sql. Func<X, bool>, linq-to-objects, linq-to-sql ( IQueryable) , - )

- Compile() , .

a.Comments.Count(CommentSpecifications.IsUnread(actorId, a.LastView).Compile())

, , linq-to-objects, linq-to-sql. , , sql, .

Update

, :

linq-to-objects linq-to-sql. Func<> Compile() , linq-to-sql .

2

, , - . Linq-to-sql , linq-to-entity, . , IQueryable<T>.

public static IQueryable<Comment> WhereIsUnread(this IQueryable<Comment> src, int userId)
{
    return src.Where(
        c =>
        !c.Deleted && c.CreatedByActorID != actorId
        && (viewed == null || c.ItemCreatedDate > c.Alert.LastView.LastViewedDate));
}

...

return (from a in alerts
        select
        new UnreadComments
            {
               TotalNumberOfUnreadComments = 
                    a.Comments.WhereIsUnRead(actorId).Count()
            })

- . , , SQL .

+3

All Articles