Как извлечь часть linq в ef для внешнего метода - PullRequest
1 голос
/ 09 апреля 2019

У меня следующая проблема.У меня есть класс, который создается с помощью запроса LINQ to EF.Класс имеет сложное поле типа string, в котором выполняется фильтрация и сортировка.Сложное поле работает так:

var result = _context.MyTable.Select(x=> new Model
{
    ...some not interesting properties
    Number =
        x.Id == 0 || !x.Created.HasValue ? null : SqlFunctions.DateName("year", x.Created) +
                                                            SqlFunctions.Replicate("-", 2 - SqlFunctions.StringConvert((double)x.Created.Value.Month).TrimStart().Length) +
                                                            SqlFunctions.Replicate("0", 2 - SqlFunctions.StringConvert((double)x.Created.Value.Month).TrimStart().Length) +
                                                            SqlFunctions.StringConvert((double)x.Created.Value.Month).TrimStart() +
                                                            SqlFunctions.Replicate("-", 2 - SqlFunctions.StringConvert((double)x.Created.Value.Month).TrimStart().Length) +
                                                            SqlFunctions.Replicate("0", 2 - SqlFunctions.DateName("dd", x.Created).Trim().Length) +
                                                            SqlFunctions.DateName("dd", x.Created).Trim()
    ...more boring properties
});

Теперь возникает вопрос - как извлечь хотя бы эту неуклюжую часть, которая преобразует обнуляемую дату в строку «гггг-ММ-дд».Было бы здорово, если бы я мог назвать это так:

var result = _context.MyTable.Select(x=> new Model
{
    ...some not interesting properties
    Number =
        x.Id == 0 || !x.Created.HasValue ? null : MyCustomConvert(x.Created)
    ...more boring properties
});

Это должно быть сделано с помощью некоторого метода, возвращающего выражение, но у меня слишком мало опыта в создании выражений для этого.Любая помощь?

1 Ответ

1 голос
/ 09 апреля 2019

Хорошо, разобрался.Огромная заслуга у Ивана Стоева.С NeinLINQ это оказалось очень просто.

Код теперь может выглядеть так:

    public static class LinqToExtensions
    {
            [InjectLambda]
            public static string ConvertToString(this DateTime v) => 
                SqlFunctions.DateName("year", v) + "-" +
                SqlFunctions.Replicate("0", 2 - SqlFunctions.StringConvert((double)v.Month).TrimStart().Length) +
                SqlFunctions.StringConvert((double)v.Month).TrimStart() + "-" +
                SqlFunctions.Replicate("0", 2 - SqlFunctions.DateName("dd", v).Trim().Length) +
                SqlFunctions.DateName("dd", v).Trim();

            public static Expression<Func<DateTime, string>> ConvertToString() => v =>
                SqlFunctions.DateName("year", v) + "-" +
                SqlFunctions.Replicate("0", 2 - SqlFunctions.StringConvert((double)v.Month).TrimStart().Length) +
                SqlFunctions.StringConvert((double)v.Month).TrimStart() + "-" +
                SqlFunctions.Replicate("0", 2 - SqlFunctions.DateName("dd", v).Trim().Length) +
                SqlFunctions.DateName("dd", v).Trim();
    }

А теперь мой код можно переписать как:

    var result = _context.MyTable.ToInjectable().Select(x=> new Model
    {
    ...some not interesting properties
        Number = x.Id == 0 || !x.Created.HasValue 
            ? null 
            : x.Created.Value.ConvertToString()
        ...more boring properties
    });

И это может быть упрощено еще больше ...

...