自定义属性和lambda表达式

dav*_*ooh 2 .net c# linq lambda linq-to-sql

我已经为LINQ-to-SQL实体添加了一个自定义属性:

public partial class User
{
    public bool IsActive
    {
        get
        {
            // note that startDate and endDate are columns of User table
            return startDate <= DateTime.Now && endDate >= DateTime.Now;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我需要将此属性与lambda表达式一起使用:

activeUsers = users.Where(u => u.IsActive);
Run Code Online (Sandbox Code Playgroud)

但是当执行此代码时,我得到了一个System.NotSupportedException.异常消息说"不支持成员'User.IsActive'的SQL转换".

有没有办法解决这个问题?

Mar*_*ell 6

IsActive你展示的是普通的C# -它会被编译为IL,将无法使用LINQ到SQL(等)进行检查,变成TSQL在数据库中执行.这里的一个选择可能是:

public static Expression<Func<User,bool>> GetIsActiveFilter() {
    return user => user.StartDate <= DateTime.Now &&
                   user.EndDate >= DateTime.Now;
}
Run Code Online (Sandbox Code Playgroud)

那么你应该可以使用:

activeUsers = users.Where(User.GetIsActiveFilter());
Run Code Online (Sandbox Code Playgroud)

或者类似 - 可能是一种扩展方法:

public static IQueryable<User> ActiveOnly(this IQueryable<User> users) {
    return users.Where(user => user.StartDate <= DateTime.Now &&
                               user.EndDate >= DateTime.Now);
}
Run Code Online (Sandbox Code Playgroud)

然后:

activeUsers = users.ActiveOnly();
Run Code Online (Sandbox Code Playgroud)

这里的区别在于我们始终使用IQueryable<T>接口和表达式树,这允许LINQ理解我们的意图,并创建合适的TSQL来实现相同的目的.