【问题标题】:Custom properties and lambda expressions自定义属性和 lambda 表达式
【发布时间】:2013-02-06 10:06:26
【问题描述】:

我已将自定义属性添加到 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;
        }
    }
}

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

activeUsers = users.Where(u => u.IsActive);

但是当这段代码被执行时,我得到一个System.NotSupportedException。异常消息显示“不支持成员 'User.IsActive' 的 SQL 转换”。

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

【问题讨论】:

  • 什么是“我的逻辑”?当它读取属性值时,可能有什么东西导致它摔倒。
  • @DarrenDavies 我编辑了我的问题

标签: c# .net linq linq-to-sql lambda


【解决方案1】:

您显示的 IsActive 是常规 C# - 它将被编译为 IL,并且不可用于 LINQ-to-SQL(等)检查并转换为 TSQL 以在数据库中执行。这里的一种选择可能是:

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

那么你应该可以使用:

activeUsers = users.Where(User.GetIsActiveFilter());

或者类似地——也许是一种扩展方法:

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

然后:

activeUsers = users.ActiveOnly();

这里的区别在于我们使用IQueryable&lt;T&gt;接口和表达式树贯穿始终,这使得LINQ能够理解我们的intent,并创建合适的TSQL来实现一样。

【讨论】:

    【解决方案2】:

    您可以尝试以下方法:

    activeUsers = users.AsEnumerable().Where(u => u.IsActive);
    

    请注意,条件 IsActive 不会被转换为 SQL,因为 IsActive 背后的逻辑从数据库的角度来看是未知的。因此数据库将对整个表 users 执行读取,并将条件应用于内存中。

    【讨论】:

      【解决方案3】:

      我用这种方式解决了我的类似问题:

      我的 ORM 是 NHibernate,底层数据库是 Oracle,当我需要添加一些像 IsActive 这样的字段时,做了这样的事情

      public partial class User
      {
         public bool IsActive{get;set;}
      }
      

      在相关的映射文件中添加类似这样的内容

      <property name="IsActive" access="property" insert="false" update="false"
        formula="case when startDate  <= sysdate And endDate  >= sysdate then 1 else 0 end" />
      

      现在你可以使用

      activeUsers = users.Where(u => u.IsActive);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多