在EF核心模型上动态获取和设置属性

时间:2020-10-07 03:44:26

标签: c# .net-core .net-core-3.1

我正在学习C#,并试图找出一种通用的方法来更新从Address继承的不同地址,并具有地址类型识别符-PhysicalAddress和MailingAddress。

该示例显示了我可以像在TypeScript中那样对模型上的访问属性进行数组设置时的操作。它表明了我正在尝试使用两种方法完成的工作,但是我还无法找出在C#中实现此目标的方法。

任何用于参考的帮助,方向或URL都很好。如果这不是设置更新的好方法,那么可以使用PerformUpdate进行正确的单个方法更新。

// Example of an actual update method:
public async Task<int> PerformUpdate(User user, User updateUser) {
  UpdateAddress(user, updateUser.PhysicalAddress);
  UpdateAddress(user, updateUser.MailingAddress);

  return await _context.SaveChangesAsync();
}

// Example of what I would like to achieve:
private void UpdateAddress(User user, Address newAddress)
{
    // Currently would be: PhysicalAddress or MailingAddress
    var addressType = newAddress.GetType().ToString();

    // Dynamically access the address on the user based on the address type
    Address oldAddress = user[addressType];
    
    // Remove the old and add the new
    if(oldAddress != null) {
        _context.Addresses.Remove(oldAddress);
    }

    user[addressType] = newAddress;
}

1 个答案:

答案 0 :(得分:0)

首先,我将看一下用例,除非必须支持大量的类,否则最好为希望支持的每个类显式创建设置器,例如,使用is关键字。但是,自您提出要求以来,我们可以滥用反射来实现此目的,例如:

class Program
    {
        static void Main(string[] args)
        {
            var address = new PhysicalAddress();
            var user = new User();
            
            // this will set user.Address1 to address
            SetAddress(user, address);

        }

        public static void SetAddress(User user, Address newAddress)
        {
            var fields = typeof(User).GetFields();

            foreach (var fieldInfo in fields)
            {
                if (fieldInfo.FieldType == newAddress.GetType())
                {
                    fieldInfo.SetValue(user, newAddress);
                }
            }
        }

        
    }

    class User
    {
        public PhysicalAddress Address1;
        public WorkAdress Address2;
    }

    class Address
    {

    }

    class PhysicalAddress: Address
    {

    }

    class WorkAdress: Address
    {

    }
```