Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DateTime对象实体框架上的动态LINQ OrderBy Date only_C#_Entity Framework_Linq_Entity Framework 6_Linq To Entities - Fatal编程技术网

C# DateTime对象实体框架上的动态LINQ OrderBy Date only

C# DateTime对象实体框架上的动态LINQ OrderBy Date only,c#,entity-framework,linq,entity-framework-6,linq-to-entities,C#,Entity Framework,Linq,Entity Framework 6,Linq To Entities,我目前正在使用该库实现动态搜索功能。我有一个要求,我需要按日期时间订购?字段只考虑日期而不考虑时间。 我正在使用EntityFramework查询SQL Azure数据库 这是示例实体 public class SampleEntity { public DateTime? DateCreated { get; set; } public bool Flag { get; set; } } 下面是查询数据库的代码 var orderByString = "DateCreated

我目前正在使用该库实现动态搜索功能。我有一个要求,我需要按日期时间订购?字段只考虑日期而不考虑时间。 我正在使用EntityFramework查询SQL Azure数据库

这是示例实体

public class SampleEntity
{
    public DateTime? DateCreated { get; set; }
    public bool Flag { get; set; }
}
下面是查询数据库的代码

var orderByString = "DateCreated.Value.Date asc, Flag"; //This is a dynamic string
var query = _context.Set<SampleEntity>().OrderBy(orderByString);
System.Linq.Dynamic解析此表达式DateCreated.Value.Date时没有任何问题,但它抛出以下错误,这是可以理解的,因为Linq to实体不支持此表达式。 请记住,这必须在IQueryable上工作,因为我需要在服务器端完成排序

LINQ to实体中不支持指定的类型成员“日期”。仅支持初始值设定项、实体成员和实体导航属性

解决方案是使用DbFunctions.TruncateTime和其他表达式。但是,这在System.Linq.Dynamic中不起作用

关于如何解决这个问题有什么想法吗。可能的解决方案是向数据库中添加另一列,只包含DateCreated的日期部分,然后查询该列。然而,我宁愿不这样做,并且正在寻找解决这个问题的其他方法。 另一种方法是动态生成lambda表达式并返回DbFunctions.TruncateTime,然后对DB执行该表达式。 欢迎您的任何意见


谢谢,

您可以使用我的答案中的方法,即使用自定义对查询表达式进行后期处理,并使用其DbFunctions等价物替换不受支持的方法。在这种特殊情况下,用方法调用替换DateTime.Date属性:

public static class QueryableExtensions
{
    public static IQueryable<T> BindDbFunctions<T>(this IQueryable<T> source)
    {
        var expression = new DbFunctionsBinder().Visit(source.Expression);
        if (expression == source.Expression) return source;
        return source.Provider.CreateQuery<T>(expression);
    }

    public static IQueryable BindDbFunctions(this IQueryable source)
    {
        var expression = new DbFunctionsBinder().Visit(source.Expression);
        if (expression == source.Expression) return source;
        return source.Provider.CreateQuery(expression);
    }

    class DbFunctionsBinder : ExpressionVisitor
    {
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.Expression != null && node.Expression.Type == typeof(DateTime) && node.Member.Name == "Date")
            {
                var dateValue = Expression.Convert(Visit(node.Expression), typeof(DateTime?));
                var methodCall = Expression.Call(typeof(DbFunctions), "TruncateTime", Type.EmptyTypes, dateValue);
                return Expression.Convert(methodCall, typeof(DateTime));
            }
            return base.VisitMember(node);
        }
    }
}
示例用法:

var orderByString = "DateCreated.Value.Date asc, Flag"; //This is a dynamic string
var query = _context.Set<SampleEntity>().OrderBy(orderByString).BindDbFunctions();

您可以使用my answer to的方法,即使用custom对查询表达式进行后期处理,并使用其DbFunctions等价物替换不受支持的方法。在这种特殊情况下,用方法调用替换DateTime.Date属性:

public static class QueryableExtensions
{
    public static IQueryable<T> BindDbFunctions<T>(this IQueryable<T> source)
    {
        var expression = new DbFunctionsBinder().Visit(source.Expression);
        if (expression == source.Expression) return source;
        return source.Provider.CreateQuery<T>(expression);
    }

    public static IQueryable BindDbFunctions(this IQueryable source)
    {
        var expression = new DbFunctionsBinder().Visit(source.Expression);
        if (expression == source.Expression) return source;
        return source.Provider.CreateQuery(expression);
    }

    class DbFunctionsBinder : ExpressionVisitor
    {
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.Expression != null && node.Expression.Type == typeof(DateTime) && node.Member.Name == "Date")
            {
                var dateValue = Expression.Convert(Visit(node.Expression), typeof(DateTime?));
                var methodCall = Expression.Call(typeof(DbFunctions), "TruncateTime", Type.EmptyTypes, dateValue);
                return Expression.Convert(methodCall, typeof(DateTime));
            }
            return base.VisitMember(node);
        }
    }
}
示例用法:

var orderByString = "DateCreated.Value.Date asc, Flag"; //This is a dynamic string
var query = _context.Set<SampleEntity>().OrderBy(orderByString).BindDbFunctions();

谢谢,如果一切正常,我们将尝试实现这一点,并将其标记为答案。谢谢,如果一切正常,我们将尝试实现这一点,并将其标记为答案。为什么这不能开箱即用?这个需求几乎存在于每个软件项目中。为什么它不能开箱即用呢?这一需求几乎存在于每个软件项目中。