C# 如何创建可转换为SQL的扩展方法

C# 如何创建可转换为SQL的扩展方法,c#,entity-framework,C#,Entity Framework,我想创建一个方法,以便在其他条件下的where子句中重用 我有这样的想法: public static bool IsActive(this Store store, DateTime date) { return store.StartDate <= date && (store.EndDate == null || storeSku.EndDate > date); } _context.Store.Where(FilterActive<Store

我想创建一个方法,以便在其他条件下的where子句中重用

我有这样的想法:

public static bool IsActive(this Store store, DateTime date)
{
    return store.StartDate <= date && (store.EndDate == null || storeSku.EndDate > date);
}
_context.Store.Where(FilterActive<Store>(new DateTime()))
我这样做的问题是代码不能翻译成sql。
您能告诉我如何将其创建为可翻译为SQL的可重用代码吗?

尝试这样做,从
IQueryable
创建一个扩展方法,并返回它,添加where子句:

public static IQueryable<Store> ActiveOnlyByDate(this IQueryable<Store> query, DateTime date) where T : class
{
    return query.Where(x => x.StartDate <= date && (x.EndDate == null || x.EndDate > date);
}

这种模式的好处在于,您可以开始将接口应用于EF模型,如果您将
StartDate
EndDate
移动到一个接口,您可以使用它创建一个扩展方法,并使代码非常可重用。

像这样尝试,您可以使用
IQueryable
创建一个扩展方法,然后返回它,添加where子句:

public static IQueryable<Store> ActiveOnlyByDate(this IQueryable<Store> query, DateTime date) where T : class
{
    return query.Where(x => x.StartDate <= date && (x.EndDate == null || x.EndDate > date);
}

这种模式的好处在于,您可以开始将接口应用于EF模型,如果您将
StartDate
EndDate
移动到一个接口,您可以使用扩展方法,并使代码非常可重用。

您可以使用表达式树将EF中的可重用方法转换为SQL,如下所示

注意:我使用这种方法而不是扩展方法。但这将根据您的需要转换为SQL查询

Expression<Func<TStore, bool>> FilterActive<TStore>(DateTime date) where TStore : ITStore
    {
        return store => store.StartDate <= date && (store.EndDate == null || store.EndDate > date);
    }
用法如下:

public static bool IsActive(this Store store, DateTime date)
{
    return store.StartDate <= date && (store.EndDate == null || storeSku.EndDate > date);
}
_context.Store.Where(FilterActive<Store>(new DateTime()))
\u context.Store.Where(FilterActive(new DateTime()))

您可以使用表达式树将EF中的可重用方法转换为SQL,如下所示

注意:我使用这种方法而不是扩展方法。但这将根据您的需要转换为SQL查询

Expression<Func<TStore, bool>> FilterActive<TStore>(DateTime date) where TStore : ITStore
    {
        return store => store.StartDate <= date && (store.EndDate == null || store.EndDate > date);
    }
用法如下:

public static bool IsActive(this Store store, DateTime date)
{
    return store.StartDate <= date && (store.EndDate == null || storeSku.EndDate > date);
}
_context.Store.Where(FilterActive<Store>(new DateTime()))
\u context.Store.Where(FilterActive(new DateTime()))

你在用EF吗?是的,我在用。这会影响到你吗?这能回答你的问题吗?我很确定您需要从方法()返回表达式,但我自己从来没有这样做过,所以不能asnwer。@gunr217我认为这不是OP想要的-看起来他们想要提取共享条件以传递给SQL到方法中,而不是在调用Where时添加更多的方法。您在使用EF吗?是的,我在使用。这会影响到你吗?这能回答你的问题吗?我很确定您需要从方法()返回表达式但是我自己从来没有这样做过,所以不能asnwer。@gunr217我不认为这是OP想要的-看起来他们想将要传递给SQL的共享条件提取到一个方法中,而不是在Where调用周围添加更多的方法。如果你想在同一Where子句上使用第二个表达式呢?(例如按其他内容过滤)您不能在同一个where中应用多个expressiontree谓词,您可以尝试我建议您使用的所有方法。where(谓词),然后使用另一个“where”在那里应用其他业务逻辑。这里很好地解释了ExpressionTree在EF查询中的重要性:如果要在同一where子句上使用第二个表达式,该怎么办?(例如按其他内容过滤)您不能在同一个where中应用多个expressiontree谓词,您可以尝试我建议您使用的所有方法。where(谓词),然后使用另一个“where”在那里应用其他业务逻辑。无论如何,这里很好地解释了ExpressionTree在EF查询中的重要性:+1是关于接口的好主意。虽然这不是我想要的。另外,理想情况下,这将与IQueryable和IEnumerable一起工作,因此我可以使用相同的代码,或者从数据库中检索其他过滤器+1,以便更好地了解接口。虽然这不是我想要的。另外,理想情况下,这将与IQueryable和IEnumerable一起工作,这样我就可以使用相同的代码,或者从的数据库中检索到其他过滤器