[英]Dynamic LINQ OrderBy Date only on DateTime Object Entity Framework
我目前正在使用Dynamic LINQ ( 原始Codeplex鏈接 )庫來實現動態搜索功能。 我有一個需要OrderBy
DateTime?
字段僅考慮日期而不是時間。 我正在使用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 Entities不支持它,因此引發了以下錯誤(可以理解)。 請記住,這必須在IQueryable上起作用( 我不能使用本文的答案 ),因為我需要在服務器端進行排序。
LINQ to Entities不支持指定的類型成員'Date'。 僅支持初始化程序,實體成員和實體導航屬性。
解決方案是使用此答案和其他答案中表示的DbFunctions.TruncateTime()
。 但是,這不適用於System.Linq.Dynamic
關於如何解決此問題的任何想法。 可能的解決方案是僅將DateCreated
的Date部分添加到數據庫中的另一列,然后查詢該列。 但是,我寧願不這樣做,而是在尋找其他解決此問題的方法。 另一種方法是動態生成lambda表達式,並返回DbFunctions.TruncateTime,然后對數據庫執行該表達式。 任何輸入表示贊賞。
謝謝,
您可以使用從我的答案到Dynamic Linq + Entity Framework的方法:動態選擇的datetime修改 ,即使用自定義ExpressionVisitor
對查詢表達式進行后處理,並用其DbFunctions
等效項替換不受支持的方法。 在這種特殊情況下,用DbFunctions.TruncateTime
方法調用替換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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.