2010-05-27 45 views
2

我有一个实体框架4.0实体对象,名为Revision w /可为空DateEffectiveFromDateEffectiveTo日期。我在想,如果有查询的速记方法基于特定QueryDate日期,而不必使用以下查询结构对象的RevisionHistory实体框架自定义查询函数

var results = EntityObject.Revisions.Where(x => 
    (x.DateEffectiveFrom == null && x.DateEffectiveTo == null) || 
    (x.DateEffectiveFrom == null && x.DateEffectiveTo >= QueryDate) || 
    (x.DateEffectiveFrom <= QueryDate && x.DateEffectiveTo == null) || 
    (x.DateEffectiveFrom <= QueryDate && x.DateEffectiveTo >= QueryDate)); 

我试图创建在下面的布尔函数Revision类:

partial class Revision 
{ 
    public bool IsEffectiveOn(DateTime date) 
    { 
     return (x.DateEffectiveFrom == null && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom == null && x.DateEffectiveTo >= date) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo >= date)); 
    } 
    ... 
} 

,然后更新查询:

var results = EntityObject.Revisions.Where(x => x.IsEffectiveOn(QueryDate)); 

但这显然d没有转化为SQL。任何想法将不胜感激。

回答

1

你可以试试Predicate Builder,看看是否转化为适当的SQL。

+0

感谢罗伯特 - 这似乎做任何IQuerable 查询(即DataContext.Revisions)的伎俩。 IEnumerable 方案的任何想法。 PS - 我很欣赏在文章中使用谓词的详细解释。 – Josh 2010-05-27 20:58:18

+0

对于IEnumerable场景,您可以看到[Dynamic Linq](http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic- query-library.aspx)的作品。请注意,动态Linq不是强类型的...你必须将你的谓词组合成字符串。 – 2010-05-27 21:11:07

0

你制作这个查询的方式部分取决于NULL对EffectiveFrom和EffectiveTo的意义。

如果EffectiveFrom为NULL,那么这是否意味着它对EffectiveTo之前的所有日期都有效,而对于NULL EffectiveTo则反之亦然?如果是这种情况,则可以使用DateTime.MinValue替代NULL EffectiveFrom值,并使用DateTime.MaxValue替代EffectiveTo。在这一点上,你可以简单地使用BETWEEN样式的查询:

Where(x => x.DateEffectiveFrom > QueryDate < x.DateEffectiveTo); 
+0

我很欣赏戴夫的回应,但我试图避免这种情况,如果我可以。 – Josh 2010-05-27 21:03:41

3

你可以让你的函数返回一个Expression,而不是一个布尔值:

partial class Revision 
{ 
    public static Expression<Func<Revision, bool>> IsEffectiveOn(DateTime date) 
    { 
     return x => (x.DateEffectiveFrom == null && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom == null && x.DateEffectiveTo >= date) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo >= date)); 
    } 
} 

然后你可以使用它:

var predicate = Revision.IsEffectiveOn(DateTime.Now); 
var results = EntityObject.Revisions.Where(predicate); 

...这将转化为SQL。

+0

谢谢克雷格 - 我给罗伯特的答案,因为他引用的文章指出了你给出的解决方案。如果可以的话,我也会让你的回应变得更糟,因为我欣赏代码。 – Josh 2010-05-27 21:01:20

+0

@Josh:我碰到你了。 – 2010-05-27 21:03:48

+0

@Robert:谢谢......作为新手的乐趣:P – Josh 2010-05-27 21:06:57