使用EntityFramework-Plus Update 方法我需要一個 MemberInitExpression 作為參數。
await _db.Users
.Where(u => u.Username == user.Username)
.UpdateAsync(x => new User { Username = "manfred" });
但是,我想以編程方式從給定的 User 對象(不僅僅是示例中的用戶名)設置所有屬性。
我想以編程方式執行此操作,以避免在開發週期後期丟失用戶對像上新添加的屬性。
編輯:我嘗試過這樣的事情,但是這不起作用,我無法設置值
Type t = User.GetType();
PropertyInfo[] props = t.GetProperties();
ParameterExpression paramExp = Expression.Parameter(typeof(User));
NewExpression newHolder = Expression.New(typeof(User));
var memberBindings = new List<MemberBinding>();
foreach (var prop in props)
{
var methodInfo = prop.GetMethod;
//var binding = Expression.Bind(methodInfo, paramExp);
var binding = Expression.Bind(methodInfo, Expression.Parameter(methodInfo.GetType(), methodInfo.Name));
memberBindings.Add(binding);
}
MemberInitExpression memberInitExpression =
Expression.MemberInit(
newHolder, memberBindings);
所以,你有變量
User user;
持有User
來自某處的實例。而你想要表達
(User x) => new User { Prop1 = user.Prop1, Prop2 = user.Prop2, ... }
這是參數x
和主體確實是 lambda 表達式MemberInitExpression
。new User
對應於NewExpression
,裡面MemberBinding
的賦值是s。的第一個參數Expression.Bind
只是PropertyInfo
,第二個參數Expression.Property
應用於保存變量值(實例)的常量表達式。它必須是常數,因為它不是來自參數。user
User
拿你的代碼
IEnumerable<PropertyInfo> props = t.GetProperties();
它可以從 EF Core 元數據中獲取,並且還必須進行調整以至少排除 PK 屬性,但假設它包含PropertyInfo
要應用的列表,則可以按如下方式構建所需的綁定:
var memberBindings = props
.Select(prop => Expression.Bind(
prop, Expression.Property(Expression.Constant(user), prop)))
.ToList();
或者,user
可以評估變量屬性並將其作為常量傳遞(不確定這是否會影響Update
方法):
var memberBindings = props
.Select(prop => Expression.Bind(
prop, Expression.Constant(prop.GetValue(user), prop.PropertyType)))
.ToList();
其餘代碼與原帖相同。ToList
不是真的需要,可以從上面的代碼中刪除,因為Expression.MemberInit
接受IEnumerable<MemberBinding>
.
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras