0

使用 Entity Framework 4.0,我用生成的代码定义了两个简单的实体,如下所示:

public partial class Person : EntityObject
{
   public string Name { ... generated code ... }
   public DateTime Birthday { ... generated code ... }
}

public partial class Sale : EntityObject
{
   public int ProductId { ... generated code ... }
   public DateTime DateSold { ... generated code ... }
}

这个特殊的例子是人为的,但代表了我面临的一个真正的问题。通常在我的代码中,我想将实体限制为出现在特定日期范围内的实体。所以我有很多实例:

entities.Sales.Where(sale => sale.DateSold > startDate && sale.DateSold < endDate);

entities.People.Where(person => person.Birthday > startDate && person.Birthday < endDate);

是否可以设置一个可以处理此问题的通用方法? 就像是

entities.Sales.WithinRange(startDate, endDate);将是完美的,我意识到我可以为 each 设置一个扩展方法IQueryable<T>,但我希望能够灵活地在公共代码中使用 WithinRange() 方法。例如:

public static IQueryable<T> GetSortedNonNullObjectsInRange<T>(this IQueryable<T> data, DateTime startDate, DateTime endDate) where T : IHasDateDefined
{
   return data.Where(entity => entity != null).WhereInRange(startDate, endDate).OrderBy(entity => entity.Date);
}

当我尝试使用通用接口(如 IHasDateDefined)时,接口上的 Date 属性会根据需要返回生日或 DateSold,但随后实体框架会抛出无法构建表达式的错误。

4

1 回答 1

0

我认为您可以通过以下方式实现您想要的:

  • 在您的实体对象上添加一个具有以下签名的静态方法: Expression> CheckWithinRange (DateTime startDate, DateTime endDate) (是的,在 Person 中,T 实际上应该替换为“Person”)

  • 使用 .tt 脚本扩展您的上下文,以便为每个表(例如 Person 和 Sale)添加一个方法,该方法使用静态添加的方法将实体对象的表达式添加到请求 IQueryable。您确实也可以为特定的 IQueryable<...> 类型创建扩展方法。

例子。

添加到 Person 类的方法:

Expression<Func<Person, bool>> CheckWithinRange (DateTime startDate, DateTime endDate) {
    return p => startDate <= p.Birthday && p.Birthday <= endDate;
}

添加到 IQueryable 的扩展方法

public IQueryable<Person> WithinRange(this IQueryable<Person> data, DateTime startDate, DateTime endDate) {
    return data.Where(Person.CheckWithinRange(startDate, endDate));
}

因此,不要向每个返回要检查的属性的类添加属性,而是将检查的逻辑添加到每个类。

于 2012-07-24T14:55:14.233 回答