Sql server EF6带DbFunctions.TruncateTime的可查询动态linq Where(谓词,值)

Sql server EF6带DbFunctions.TruncateTime的可查询动态linq Where(谓词,值),sql-server,entity-framework-6,dynamic-linq,Sql Server,Entity Framework 6,Dynamic Linq,在我的简化示例中,我有一个具有以下属性的对象: 名称(字符串) 生日时间戳(日期时间) 我需要能够以以下方式构建动态查询 var predicate = "Name = @0"; var values = new object[]{"Ed"}; myIQueryableDataSource.Where(predicate, values) 这工作很好。现在我想比较一下我的约会时间 var predicate = "BirthDateTimeStamp >= @0"; var valu

在我的简化示例中,我有一个具有以下属性的对象:

  • 名称(字符串)
  • 生日时间戳(日期时间)
我需要能够以以下方式构建动态查询

var predicate = "Name = @0";
var values = new object[]{"Ed"};
myIQueryableDataSource.Where(predicate, values)
这工作很好。现在我想比较一下我的约会时间

var predicate = "BirthDateTimeStamp >= @0";
var values = new object[]{someDateTime};
这也很有效。但是,当比较日期时间时,我实际上想做的是,当进行等号比较时,这个问题会更好地显示出来

var predicate = "BirthDateTimeStamp.Date >= @0";
这是不可能的,因为SQL server的EF无法识别日期属性

var predicate = "System.Data.Entity.DbFunctions.TruncateTime(BirthDateTimeStamp) >= @0";
这也不起作用,因为我只能访问谓词中的对象属性

如何以这种方式解决此问题,使谓词保持字符串格式。这段代码只是用于我的查询的现有大型解析器的一部分,因此无法完全重写。

请参阅

System.Linq.Dynamic正在解析作为C#给出的表达式,但无法识别类DbFunctions。但是,您可以将DbFunctions作为预定义类型进行修补:

var type = typeof( DynamicQueryable ).Assembly.GetType( "System.Linq.Dynamic.ExpressionParser" );

FieldInfo field = type.GetField( "predefinedTypes", BindingFlags.Static | BindingFlags.NonPublic );

Type[] predefinedTypes = (Type[])field.GetValue( null );

Array.Resize( ref predefinedTypes, predefinedTypes.Length + 1 );
predefinedTypes[ predefinedTypes.Length - 1 ] = typeof( DbFunctions );

field.SetValue( null, predefinedTypes );
然后你可以用

var predicate = "DbFunctions.TruncateTime(BirthDateTimeStamp) >= @0";

@RockResolve给出的答案确实有效,但有点像黑客。Linq Dynamics提供了添加自定义函数的功能

public class CustomTypeProvider: IDynamicLinkCustomTypeProvider
{
    public HashSet<Type> GetCustomTypes()
    {
      HashSet<Type> types = new HashSet<Type>();
      // adding custom types
      types.Add(typeof(DbFunctions)); 
      return types;
    }
}

// use below line to add this to linq
System.Linq.Dynamics.GlobalConfig.CustomTypeProvider = new CustomTypeProvier();
公共类CustomTypeProvider:IDynamicLinkCustomTypeProvider
{
公共HashSet GetCustomTypes()
{
HashSet types=新的HashSet();
//添加自定义类型
添加(typeof(DbFunctions));
返回类型;
}
}
//使用下面的行将其添加到linq
System.Linq.Dynamics.GlobalConfig.CustomTypeProvider=新的CustomTypeProvider();