将属性从对象复制到另一个的优雅方法

时间:2016-02-20 11:16:54

标签: c# .net

我有一个小型集成服务,它接收XML文件并解析它。 此外,我还从提供的XSD创建了用于反序列化XML数据的类。在解析期间,我需要将这些XSD生成的类中的属性复制到我在数据层中使用的属性。这是我的方法的一个例子

"The specified type member 'UserName' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

有些时候,大量的房产非常大。是否有更复制的方式来复制这些属性?

3 个答案:

答案 0 :(得分:1)

自从很久以前,Automapper一直在那里。试过并测试过。 http://automapper.org/

以下是一个例子:

using System;
using AutoMapper;   

public class Program
{
    class SupplierInfo
    {
        public SupplierInfo( string name, string shortName, string brandName ) {
            Name = name; 
            ShortName = shortName; 
            BrandName = brandName;
        }
        public string Name {get; private set; }
        public string ShortName {get; private set; }
        public string BrandName {get; private set; }
    }

    class Supplier
    {
        public string name {get; set; }
        public string shortName {get; set; }
        public string brandName {get; set; }
    }       

    public static void Main()
    {
        var dto = new Supplier() {
            name = "Name 1",
            shortName = "Short Name 1",
            brandName = "Brand Name 1"
        };


        //From the tutorial:
        //You only need one MapperConfiguration instance typically per AppDomain and should be instantiated during startup.
        var config = new MapperConfiguration(cfg => cfg.CreateMap<Supplier, SupplierInfo>());

        var mapper = config.CreateMapper();

        SupplierInfo info = mapper.Map<SupplierInfo>(dto);

        Console.WriteLine( info.Name );
        Console.WriteLine( info.ShortName );
        Console.WriteLine( info.BrandName );
    }
}

官方入门指南可在https://github.com/AutoMapper/AutoMapper/wiki/Getting-started

找到

答案 1 :(得分:1)

首先,安装EntityLite.Core:

PM> Install-Package EntityLite.Core

然后使用它:

using inercya.EntityLite.Extensions;
...
supplierInfo.AssignPropertiesFrom(supplier);

EntityLite是我开发的微型ORM。它有一些小宝石: - )

编辑:

我想你可能不想安装EntityLite.Core只是为了将一些属性从一个对象复制到另一个对象。所以这里有一个AssignPropertiesFrom扩展方法的实现,它使用Reflection:

public static class ObjectExtensions
{
    public static void AssignPropertiesForm(this object target, object source)
    {
        if (target == null || source == null) throw new ArgumentNullException();
        var targetPropertiesDic = target.GetType().GetProperties().Where(p => p.CanWrite).ToDictionary(p => p.Name, StringComparer.CurrentCultureIgnoreCase);
        foreach (var sourceProp in source.GetType().GetProperties().Where(p => p.CanRead))
        {
            PropertyInfo targetProp;
            if (targetPropertiesDic.TryGetValue(sourceProp.Name, out targetProp))
            {
                targetProp.SetValue(target, sourceProp.GetValue(source, null), null);
            }
        }
    }
}

顺便说一下,这不是EntityLite实现。 EntityLite使用动态IL生成。

答案 2 :(得分:1)

我很高兴能够对此进行更正,但我总是找到自动播放器(根据其他答案),它按名称/约定映射属性值,在生产代码中使用有点可怕。

我真的没有一个像样的替代方案,但我更喜欢按照您的代码示例手动执行 - 它更容易阅读和调试,如果您最终重命名类中的任何属性,很明显复制代码被破坏(或者如果您使用某些IDE工具重命名该属性,它将相应地更改复制代码。)