首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >强制将DateTimeOffset转换为Nullable<DateTimeOffset>

强制将DateTimeOffset转换为Nullable<DateTimeOffset>
EN

Stack Overflow用户
提问于 2018-07-24 15:59:42
回答 1查看 1.3K关注 0票数 1

我需要编写一个动态构建LINQ查询表达式的函数。我无法构建一个Equals表达式来将DateTimeOffsetDateTimeOffset?进行比较(Expression.Equal抱怨类型不能通过比较),也无法将DateTimeOffset转换为DateTimeOffset?以使Expression.Equal工作,因为无论使用何种转换策略,DateTimeOffset都不能转换为DateTimeOffset?

MyEntity.cs:

代码语言:javascript
复制
public class MyEntity {
    public DateTimeOffset? DeliverOn;
}

Main.cs:

代码语言:javascript
复制
public void Test {
    IQueryable<MyEntity> MyEntityList = Enumerable.Empty<MyEntity>().AsQueryable();
    DateTimeOffset? dt1 = new DateTimeOffset(2018, 01, 01, 00, 00, 00, TimeSpan.Zero);
    var expr = WhereEquals(MyEntityList, t => t.DeliverOn, dt1);
}

ExpressionBuilder.cs:

代码语言:javascript
复制
public static IQueryable<TSource> WhereEquals<TSource, TValue>(IQueryable<TSource> source, Expression<Func<TSource, TValue>> selector, TValue value) {
    return source.Where(Expression.Lambda<Func<TSource, bool>>(Expression.Equal(selector.Body, Expression.Constant(value)), selector.Parameters));
}

投球:System.InvalidOperationException: 'The binary operator Equal is not defined for the types 'System.Nullable``1[System.DateTimeOffset]' and 'System.DateTimeOffset'.'

尽管dt1在编译时是一个DateTimeOffset?,但在运行时,C#认为dt1是一个DateTimeOffset。我能解决这个问题吗?

我试过:

  • DateTimeOffset? dt1 = (DateTimeOffset?)new DateTimeOffset(2018, 01, 01, 00, 00, 00, TimeSpan.Zero);
  • DateTimeOffset? dt1 = (DateTimeOffset?)(object)new DateTimeOffset(2018, 01, 01, 00, 00, 00, TimeSpan.Zero);
  • DateTimeOffset? dt1 = (DateTimeOffset?)Convert.ChangeType(new DateTimeOffset(2018, 01, 01, 00, 00, 00, TimeSpan.Zero), typeof());

然而,dt1仍然是一个DateTimeOffset

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-24 16:32:39

使用重载Expression.Constant(Object, Type)指定要比较使用的值的类型。

在不指定类型的情况下,Nullable<DateTimeOffset>将被解压缩为简单的DateTimeOffset

代码语言:javascript
复制
void Main()
{
    //IQueryable<MyEntity> MyEntityList = Enumerable.Empty<MyEntity>().AsQueryable();
    var MyEntityList = new List<MyEntity>();
    MyEntityList.Add(new MyEntity { DeliverOn = new DateTimeOffset(2018, 01, 01, 00, 00, 00, TimeSpan.Zero) });
    DateTimeOffset? dt1 = new DateTimeOffset(2018, 01, 01, 00, 00, 00, TimeSpan.Zero);
    var expr = WhereEquals<MyEntity, DateTimeOffset?>(MyEntityList.AsQueryable(), t => t.DeliverOn, (DateTimeOffset?)dt1);
    Console.WriteLine($"{expr.Count()} item(s) found");

    // Output:
    // selector.GetType() is System.Linq.Expressions.Expression`1[System.Func`2[UserQuery + MyEntity, System.Nullable`1[System.DateTimeOffset]]]
    // typeof(TValue) is System.Nullable`1[System.DateTimeOffset]
    // value.GetType() is System.DateTimeOffset
    // 1 item(s) found
}

public class MyEntity
{
    public DateTimeOffset? DeliverOn;
}

public static IQueryable<TSource> WhereEquals<TSource, TValue>(IQueryable<TSource> source, Expression<Func<TSource, TValue>> selector, TValue value)
{
    Console.WriteLine($"selector.GetType() is {selector.GetType()}");
    Console.WriteLine($"typeof(TValue) is {typeof(TValue)}");
    Console.WriteLine($"value.GetType() is {value.GetType()}");
    return source.Where(Expression.Lambda<Func<TSource, bool>>(Expression.Equal(selector.Body, Expression.Constant(value, typeof(TValue))), selector.Parameters));
}

相关的,虽然接受的答案使用Expression.Convert(),我认为这是不必要的。

Working with nullable types in Expression Trees

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51503045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档