【问题标题】:Entity Framework Custom Query Function实体框架自定义查询功能
【发布时间】:2010-05-27 16:43:52
【问题描述】:

我有一个名为 Revision 的实体框架 4.0 实体对象,带有可空的 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));

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

【问题讨论】:

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


    【解决方案1】:

    你可以让你的函数返回一个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。

    【讨论】:

    • 谢谢克雷格 - 我给罗伯特的答案,因为他引用的文章指出了你在上面给出的解决方案。如果可以的话,我也会提高你的回复,因为我很欣赏代码。
    • @Robert:谢谢......成为新手的乐趣:P
    【解决方案2】:

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

    【讨论】:

    • 感谢 Robert - 这似乎对任何 IQuerable 查询(即 DataContext.Revisions)都有效。 IEnumerable 场景的任何想法。 PS - 我也很欣赏文章中对谓词使用的详细解释。
    • 对于 IEnumerable 场景,您可以查看Dynamic Linq 是否有效。请注意,Dynamic Linq 不是强类型...您必须将谓词组合为字符串。
    【解决方案3】:

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

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

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

    【讨论】:

    • 感谢 Dave 的回复,但如果可以的话,我会尽量避免这种情况。
    猜你喜欢
    • 2013-01-22
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    相关资源
    最近更新 更多