如何提取部分linq到ef以使用外部方法

时间:2019-04-09 09:16:27

标签: c# linq entity-framework-6 linq-expressions

我有以下问题。我有一个用LINQ to EF查询实例化的类。类具有一个字符串类型的棘手字段,在该字段上执行了一些过滤和排序。棘手的字段是这样的:

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
});

现在,问题是-如何至少提取该尴尬的部分,该部分将可为空的日期转换为“ yyyy-MM-dd”字符串。如果我可以这样称呼它,那将很酷:

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 个答案:

答案 0 :(得分:1)

好,知道了。伊万·斯托耶夫(Ivan Stoyev)功不可没。事实证明,使用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
    });

它甚至可以进一步简化...