实体框架自定义查询功能

时间:2010-05-27 16:43:52

标签: .net entity-framework linq-to-entities

我有一个名为Revision的实体框架4.0实体对象w / Nullable DateEffectiveFromDateEffectiveTo日期。我想知道是否有一种基于特定RevisionHistory日期查询对象QueryDate的简便方法,而不必使用以下查询结构:

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));

但这显然不会转化为SQL。任何想法都会非常感激。

3 个答案:

答案 0 :(得分:3)

你可以让你的函数返回Expression,而不是bool:

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。

答案 1 :(得分:1)

您可以尝试Predicate Builder,看看是否转换为适当的SQL。

答案 2 :(得分:0)

您制作此查询的方式部分取决于NULL对EffectiveFrom和EffectiveTo的含义。

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

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