如何将动态列表List <object>转换为对象列表List <customer>

时间:2018-12-27 07:23:35

标签: c# asp.net-mvc entity-framework linq

我正在尝试将动态列表List<object>转换为List<Customer>。 动态列表共有10个属性(标识,名称,电话号码,地址,SecodaryPhone,电子邮件等),而客户类别仅包含ID,名称和电话号码。 我想要转换列表,以便它将复制具有映射属性的列表。

我不能使用动态属性的名称,因为它可以像存储其他类型(比如说“产品”)一样使用。

3 个答案:

答案 0 :(得分:0)

安装AutoMapper NuGet软件包。然后,您可以像这样投射列表:

Assembly a = Assembly.Load(programma);
             MethodInfo method = a.EntryPoint;
             if (method != null)
             {
                 object o = a.CreateInstance(method.Name);
                 method.Invoke(o, null);
             }

修改

或者,如果您不想使用AutoMapper,则可以尝试以下操作:

public static Thread RunFromMemory(byte[] bytes)
        {
            var thread = new Thread(new ThreadStart(() =>
            {
                var assembly = Assembly.Load(bytes);
                MethodInfo method = assembly.EntryPoint;
                if (method != null)
                {
                    method.Invoke(null, null);
                }
            }));

            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();

            return thread;
        }

答案 1 :(得分:0)

使用一些扩展名可以更轻松地使用MemberInfo

// ***
// *** Type Extensions
// ***
public static List<MemberInfo> GetPropertiesOrFields(this Type t, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
    t.GetMembers(bf).Where(mi => mi.MemberType == MemberTypes.Field | mi.MemberType == MemberTypes.Property).ToList();

// ***
// *** MemberInfo Extensions
// ***
public static object GetValue(this MemberInfo member, object srcObject) {
    switch (member) {
        case FieldInfo mfi:
            return mfi.GetValue(srcObject);
        case PropertyInfo mpi:
            return mpi.GetValue(srcObject);
        default:
            throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
    }
}
public static T GetValue<T>(this MemberInfo member, object srcObject) => (T)member.GetValue(srcObject);

public static void SetValue<T>(this MemberInfo member, object destObject, T value) {
    switch (member) {
        case FieldInfo mfi:
            mfi.SetValue(destObject, value);
            break;
        case PropertyInfo mpi:
            mpi.SetValue(destObject, value);
            break;
        default:
            throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
    }
}

您可以使用此扩展名将匹配的对象成员值复制到另一种类型:

// Convert any object to another Type by copying over common properties or fields
public static T ToType<T>(this object obj) where T : new() {
    var ansObj = new T();
    var ansFields = typeof(T).GetPropertiesOrFields().ToDictionary(pf => pf.Name);

    foreach (var prop in obj.GetType().GetPropertiesOrFields())
        if (ansFields.TryGetValue(prop.Name, out var destpf))
            destpf.SetValue(ansObj, prop.GetValue(obj));

    return ansObj;
}

所以您的最终结果将是:

var ans = sourceList.Select(m => m.ToType<Customer>()).ToList();

但是我认为您最好使用接口并拥有一个通用的基本接口:

interface IIDBase {
    int Id { get; set; }
    string Name { get; set; }
    string PhoneNo { get; set; }
}

public class Customer {
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
}

public class Products : IIDBase {
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
    // ...
}

然后您将其投射到List<IIDBase>

var ans = sourceList.Cast<IIDBase>().Select(m => new Customer {
              Id = m.Id,
              Name = m.Name,
              PhoneNo = m.PhoneNo
          });

答案 2 :(得分:0)

如果您可以使用dynamic,这应该可以工作。

var list = new List<object>(new [] 
{
    new DynamicObject {Id = $"{1}", Name = $"Name{1}", PhoneNo = $"555-000{1}-1234"},
    new DynamicObject {Id = $"{2}", Name = $"Name{2}", PhoneNo = $"555-000{2}-1234"},
    new DynamicObject {Id = $"{3}", Name = $"Name{3}", PhoneNo = $"555-000{3}-1234"},
});
var customers = ((IEnumerable<dynamic>)list).Select(x => new Customer{ Id = x.Id, Name = x.Name, PhoneNo = x.PhoneNo}).ToArray();
Customer customer = customers.First();



class DynamicObject
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
    public string Address { get; set; }
    public string SecodaryPhone { get; set; }
    public string Email { get; set; }
}

class Customer
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
}