通过引用lambda表达式为属性赋值

本文关键字:属性 赋值 表达式 lambda 引用 | 更新日期: 2024-07-10 18:05:04

我有两个对象(一个DTO和一个Entry Framework对象),如果DTO中的相应值不同,我想更新EF实体。我设想会这样做:UpdateIfDifferent(dtoObject, x => x.MailStatus, efObject, r => r.MailStatus); UpdateIfDifferent(dtoObject, x => x.WebStatus, efObject, r => r.WebStatus);

private void UpdateIfDifferent<TOriginal, TOriginalProperty, TUpdated, TUpdatedProperty>
  (TOriginal original, Expression<Func<TOriginal, TOriginalProperty>> originalProperty, 
TUpdated updated, Expression<Func<TUpdated, TUpdatedProperty>> updatedProperty)
  {
      if (!originalProperty.Compile()(original).Equals(updatedProperty.Compile()(updated)))  {
        // how do I assign back to original from updated?
        }
      }
    }

我相信以下内容应该有效,但我不知道如何将值分配回efObject。有人能给我线索吗?

通过引用lambda表达式为属性赋值

您可以这样做:

public static void Main()       
{
    var original = new TestEntity();
    original.Name = "test";
    var dto = new TestDTO();
    dto.FirstName = "New Value";
    UpdateIfDifferent(original, o => o.Name, dto, d => d.FirstName);
    Console.WriteLine(original.Name);
}
private static void UpdateIfDifferent<TOriginal, TOriginalProperty, TUpdated, TUpdatedProperty>
    (TOriginal original, Expression<Func<TOriginal, TOriginalProperty>> originalProperty, 
        TUpdated updated, Expression<Func<TUpdated, TUpdatedProperty>> updatedProperty)
{
  if (!originalProperty.Compile()(original).Equals(updatedProperty.Compile()(updated)))  
  {
        var updatedMember = (updatedProperty.Body as MemberExpression).Member as PropertyInfo;
        var updatedValue = updatedMember.GetValue(updated);
        var member = (originalProperty.Body as MemberExpression).Member as PropertyInfo;
        member.SetValue(original, updatedValue);
    }
}
public class TestEntity
{
    public string Name {get;set;}
}
public class TestDTO
{
    public string FirstName {get;set;}
}

以下是DotNetFiddle上的一个工作示例-https://dotnetfiddle.net/k1qLZH

此示例仅用于属性和成员访问。因此,如果您的表达式将具有另一个类似于签名的方法、子属性、字段访问,那么此代码将失败。

另一种不需要lambda编译的方法可能需要一些时间:

private static void UpdateIfDifferent<TOriginal, TOriginalProperty, TUpdated, TUpdatedProperty>
    (TOriginal original, Expression<Func<TOriginal, TOriginalProperty>> originalProperty, 
        TUpdated updated, Expression<Func<TUpdated, TUpdatedProperty>> updatedProperty)
{
    var updatedMember = (updatedProperty.Body as MemberExpression).Member as PropertyInfo;
    var updatedValue = updatedMember.GetValue(updated);
    var originalMember = (originalProperty.Body as MemberExpression).Member as PropertyInfo;
    var originalValue = originalMember.GetValue(original);
    if (!object.Equals(updatedValue, originalValue))
        originalMember.SetValue(original, updatedValue);
}