I have the following object received from Angular client application in ASP.NET Core:
public class ModelFromClient
{
public string name {get;set;} //Database field is Name
public int qunatity {get;set;} //Database field is Quantity
}
And I have a EF Table class:
[Table("MyTable")]
public class MyRow
{
public int Id {get;set;}
public string Name {get;set;}
public int Qunatity {get;set;}
}
Now I need to create expression from ModelFromClient
to Expression<Func<MyRow, MyRow>>
and I need it with generic.
Without generics solution would be:
public Expression<Func<MyRow, MyRow>> ToExpression(ModelFromClient Model)
{
Expression<Func<MyRow, MyRow>> result = (t) => new MyRow()
{
Name = Model.name,
Quantity = Model.qunatity
};
return result;
}
But I would like something like that:
public Expression<Func<T, T>> ToExpression<T>(object Model) where T: new()
{
Expression<Func<T, T>> result = (t) => new T();
foreach(var prop in Model.GetType().GetProperties())
{
//compile error Fields does not exists.
result.Body.Fields.Add(prop.Name.Capitalize(), prop.GetValue(Model, null)); //capitalize returns Name from input name
}
return result;
}
I need expression to pass it to Update extension method of EntityFramework-Plus.
Disclaimer: I'm the owner of the project Entity Framework Plus
Here is a fiddle to get you started: 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);
}
}
Disclaimer: I'm the owner of the project Eval-Expression.NET
This library is not free but allows you to create code dynamically at runtime. Once you get familiar, you can do pretty much anything you want way more easily than with the previous solution.
// Register your type
EvalManager.DefaultContext.RegisterType(typeof(MyRow));
// Register extension methods once from Z.EntityFramework.Plus
EvalManager.DefaultContext.RegisterExtensionMethod(typeof(BatchUpdate));
Eval.Execute("query.Update(x => new MyRow() { Id = 1, Name = 'Z_Name', Qunatity = 2});", new {query});