【问题标题】:How do you create Expression<Func<T, T>> given the property names of T to map?给定要映射的 T 的属性名称,如何创建 Expression<Func<T, T>>?
【发布时间】:2017-12-01 05:34:08
【问题描述】:

以下是所需函数的外观:

 public static Expression<Func<T, T>> GetExpression<T>(string propertyNames) where T : class
 {
       var properties = propertyNames.Split(
            new char[] { ',' }, 
            StringSplitOptions.RemoveEmptyEntries
        ).ToList();

       //need help here
 }

目前我正在这样做:

_context.Questions.Select(q => 
                new Question() {
                    QuestionId = q.QuestionId,
                    QuestionEnglish = q.QuestionEnglish
                }
).ToList();

我想将其替换为:

_context.Questions.Select(GetExpression<Question>("QuestionId, QuestionInEnglish")).ToList();

任何帮助将不胜感激。

【问题讨论】:

  • 我认为这不会是一个改进。看看 AutoMapper 什么的。
  • 显式字符串属性名称是重构灾难的秘诀。如果您厌倦了每次手动编写投影,请将投影存储在某处或按照 AluanHaddad 的建议使用 automapper。但是,也许您应该禁用代理创建和查询 _context.Questions.AsNoTracking()... 而不是将结果投影到它自己的类型?

标签: entity-framework linq expression


【解决方案1】:

你可以这样做;

    public static Func<T, T> GetExpression<T>(string propertyNames)
    {
        var xParameter = Expression.Parameter(typeof(T), "parameter");

        var xNew = Expression.New(typeof(T));

        var selectFields = propertyNames.Split(',').Select(parameter => parameter.Trim())
            .Select(parameter => {

                    var prop = typeof(T).GetProperty(parameter);

                    if (prop == null) // The field doesn't exist
                    {
                        return null;
                    }
                    var xOriginal = Expression.Property(xParameter, prop);

                    return Expression.Bind(prop, xOriginal);
                }
            ).Where(x => x != null);

        var lambda = Expression.Lambda<Func<T, T>>(Expression.MemberInit(xNew, selectFields), xParameter);

        return lambda.Compile();
    }

用法;

    var list = new List<Question>{new Question{QuestionEnglish = "QuestionName",QuestionId = 1}};
    var result = list.Select(GetExpression<Question>("QuestionId, QuestionEnglish"));

【讨论】:

  • 因为我需要表达式本身,即 Expression>,我不得不删除 Compile 方法调用。其他一切都像它应该的那样工作。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多