객체에서 표현식 만들기

c# entity-framework-plus expression reflection

문제

ASP.NET Core의 Angular 클라이언트 응용 프로그램에서 다음 객체를 받았습니다.

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

그리고 나는 EF Table 클래스를 가지고있다 :

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

이제 ModelFromClient 에서 Expression<Func<MyRow, MyRow>>Expression<Func<MyRow, MyRow>> 을 만들어야하고 일반화해야합니다. 제네릭 솔루션이 없다면 :

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

그러나 나는 그런 것을 좋아할 것이다 :

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

EntityFramework-Plus의 Update 확장 메소드에 전달하는 표현식이 필요합니다.

수락 된 답변

면책 조항 : 저는 Entity Framework Plus 프로젝트의 소유자입니다.

시작을위한 바이올린은 다음과 같습니다. https://dotnetfiddle.net/JY0wzw

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

면책 조항 : 저는 프로젝트 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);
    }
}

인기 답변

@ 조나단 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);
}

누군가가 동일한 솔루션을 검색 할 경우에 대비해.




아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.