实体框架Linq将lambda表达式嵌入到可重用函数

时间:2015-11-09 18:51:32

标签: entity-framework linq linq-to-sql lambda linq-to-entities

当使用Linq with Entity Framework查询数据库时,有没有办法减少重复的lambdas?例如:

db.Users.FirstOrDefault(x => x.Username == "MM001" && x.Type == 1 && x.IsActive == True && x.ExpiryDate > DateTime.Now);

我想把它变成只是:

db.Users.FirstOrDefault(x => x.Username == "MM001" && x.IsActiveStaff());

我尝试在我的用户POCO中编写如下方法:

public bool IsActiveStaff()
{
    return Type == 1 && IsActive == True && ExpiryDate > DateTime.Now;
}

但是,我收到以下错误:LINQ to Entities无法识别方法'Boolean IsActiveStaff()'方法,并且此方法无法转换为商店表达式。

我意识到这是因为LINQ To Entities无法将此方法转换为SQL表达式,但有什么方法可以让它工作吗?

我知道我可以编写一个查询命令类,它只需要将一个Username作为参数,并将所有逻辑放在那里,但我想知道你是否可以将一系列lambdas嵌入到方法中或扩展方法等,并在需要时使用它们,如上例所示。

2 个答案:

答案 0 :(得分:4)

我更喜欢使用扩展方法,如:

public static class UsersExtensions
{
  public static IQueryable<User> IsActive(this IQueryable<User> u)
  {
    // Should really use UTC
    return u.Where(x=>x.IsActive && x.ExpiryDate>DateTime.Now);
  }
  public static IQueryable<User> IsStaff(this IQueryable<User> u)
  {
    return u.Where(x=>x.Type==1);
  }
}

像(使用完整智能感知)一样使用:

var result=db.Users
  .IsActive()
  .IsStaff()
  .FirstOrDefault(x=>x.UserName=="MM001");

答案 1 :(得分:2)

创建适当类型的表达式:

Expression<Func<User, bool>> IsActiveStaff = x => x.Type == 1 && x.IsActive && x.ExpiryDate > DateTime.Now;

然后:

db.Users.Where(IsActiveStaff).FirstOrDefault(x => x.Username == "MM001");