从对象构建表达式

时间:2017-11-24 07:52:49

标签: c# reflection expression entity-framework-plus

我从ASP.NET Core中的Angular客户端应用程序收到以下对象:

wordpress

我有一个EF Table课程:

public class ModelFromClient
{
  public string name {get;set;}      //Database field is Name
  public int qunatity {get;set;}     //Database field is Quantity
}

现在我需要创建从[Table("MyTable")] public class MyRow { public int Id {get;set;} public string Name {get;set;} public int Qunatity {get;set;} } ModelFromClient的表达式,我需要使用泛型。 没有泛型解决方案将是:

Expression<Func<MyRow, MyRow>>

但我想要这样的事情:

public Expression<Func<MyRow, MyRow>> ToExpression(ModelFromClient Model)
{
    Expression<Func<MyRow, MyRow>> result = (t) => new MyRow()
    {
        Name = Model.name, 
        Quantity = Model.qunatity
    };
    return result;
}

我需要表达式将其传递给EntityFramework-Plus的Update扩展方法。

2 个答案:

答案 0 :(得分:3)

免责声明:我是该项目的所有者Entity Framework Plus

这是帮助您入门的小提琴:https://dotnetfiddle.net/JY0wzw

Handler

免责声明:我是该项目的所有者Eval-Expression.NET

此库不是免费的,但允许您在运行时动态创建代码。一旦熟悉,您可以比以前的解决方案更轻松地完成您想要的任何事情。

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

public class Program
{
    public class MyRow
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Qunatity { get; set; }
    }

    public static void Main()
    {
        var type = typeof(MyRow);
        var constructorInfo = type.GetConstructor(new Type[0]);
        var newExpression = Expression.New(constructorInfo);

        var memberInits = new List<MemberAssignment>();
        foreach (var prop in type.GetProperties())
        {
            if (prop.Name == "Id")
            {
                memberInits.Add(Expression.Bind(prop, Expression.Constant(1)));
            }
            else if (prop.Name == "Name")
            {
                memberInits.Add(Expression.Bind(prop, Expression.Constant("Z_Name")));
            }
            else if (prop.Name == "Qunatity")
            {
                memberInits.Add(Expression.Bind(prop, Expression.Constant(2)));
            }
        }

        var expression = Expression.MemberInit(newExpression, memberInits);

        // FOR testing purpose
        var compiledExpression = Expression.Lambda<Func<MyRow>>(expression).Compile();
        var myRow = compiledExpression();

        Console.WriteLine(myRow.Id);
        Console.WriteLine(myRow.Name);
        Console.WriteLine(myRow.Qunatity);
    }
}

答案 1 :(得分:1)

正如@Jonathan Magnan所说(谢谢乔纳森),他的回答指出了我正确的方向:

public static Expression<Func<T, T>> ToExpressionGeneric<T>(this object Model) where T : new()
{
    var type = typeof(T);
    var constructorinfo = type.GetConstructor(new Type[0]);
    var newExpression = Expression.New(constructorinfo);

    var memberInits = new List<MemberAssignment>();

    var modelProperties = Model.GetType().GetProperties();
    foreach (var prop in type.GetProperties())
    {
        var modelProperty = modelProperties.Where(t => t.Name == prop.Name.FirstLetterToLowerCase()).SingleOrDefault();
        if (modelProperty != null)
            memberInits.Add(Expression.Bind(prop, Expression.Constant(modelProperty.GetValue(Model, null))));
    }

    var expression = Expression.MemberInit(newExpression, memberInits);

    var p = Expression.Parameter(typeof(T), "p");

    return Expression.Lambda<Func<T, T>>(expression, p);
}

public static string FirstLetterToLowerCase(this string s)
{
    if (string.IsNullOrEmpty(s))
        throw new ArgumentException("There is no first letter");

    char[] a = s.ToCharArray();
    a[0] = char.ToLower(a[0]);
    return new string(a);
}

以防万一有人会搜索相同的解决方案。