Создайте деревья выражений, которые вызывают метод с типом null - PullRequest
2 голосов
/ 09 января 2020

Я хотел бы достичь этого результата, используя деревья выражений:

x.DataMod == null ? string.Empty : x.DataMod.Value.ToShortDateString()

Я пытаюсь использовать Expression.Condition, но я не знаю, как позвонить ToShortDateString().

Мне нужен результат в запросе Linq GroupBy.

var grouped = context.Receipt.GroupBy(x => (x.DataMod == null ? string.Empty : x.DataMod.Value.ToShortDateString()) + ";" + x.DataOraDocumento.ToShortDateString() + ";" + x.Cassa.Descrizione + ";" + x.Sezionale.Descrizione).ToList();

Спасибо

1 Ответ

0 голосов
/ 23 января 2020

Как предлагается в комментариях, вы должны использовать Expression.Call, чтобы создать выражение для ToShortDateString вызова метода. Я составил образец для слегка упрощенной версии исходного выражения. См. Встроенные комментарии.

x.DataMod.HasValue ? x.DataMod.Value.ToShortDateString() : string.Empty

void Main()
{
    var now = DateTime.UtcNow;
    var tomorrow = now.AddDays(1);

    var data = new Test[] {
        new Test { DataMod = null },
        new Test { DataMod = now },
        new Test { DataMod = null },
        new Test { DataMod = tomorrow },
        new Test { DataMod = null },
        new Test { DataMod = now }
    };

    var keySelector = BuildSelector();

    var groups = data
        .GroupBy(keySelector)
        .ToList();

    foreach (var group in groups)
    {
        Console.WriteLine($"Group = \"{group.Key}\"");
        Console.WriteLine($"Items = {group.Count()}");
        Console.WriteLine();
    }
}

class Test
{
    public DateTime? DataMod { get; set; }
}

Func<Test, string> BuildSelector()
{
    // Builds delegate for the Expression: 
    // x => x.DataMod.HasValue ? x.DataMod.Value.ToShortDateString() : string.Empty

    // Expression for: x
    var x = Expression.Parameter(typeof(Test), "x");

    // Expression for: x.DataMod.HasValue
    var testExpr = Expression.Property(
        Expression.Property(
            x, 
            nameof(Test.DataMod)
        ),
        nameof(Nullable<DateTime>.HasValue)
    );

    // Expression for: x.DataMod.Value.ToShortDateString()
    var ifTrueExpr = Expression.Call(

        // Expression for: x.DataMod.Value
        Expression.Property(
            Expression.Property(
                x,
                nameof(Test.DataMod)
            ),
            nameof(Nullable<DateTime>.Value)
        ),

        // Expression for: ToShortDateString
        typeof(DateTime).GetMethod(
            nameof(DateTime.ToShortDateString)
        )

        /* args if any */
    );

    // Expression for: string.Empty
    var ifFalseExpr = Expression.Field(
        null,
        typeof(string).GetField(nameof(string.Empty))
    );

    // Expression for: x => x.DataMod.HasValue ? x.DataMod.Value.ToShortDateString() : string.Empty
    var conditionExpr = Expression.Condition(
        testExpr, 
        ifTrueExpr, 
        ifFalseExpr);

    // Compile to a delegate
    var lambda = Expression.Lambda<Func<Test, string>>(conditionExpr, x);
    return lambda.Compile();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...