我有一个小型集成服务,它接收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."
有些时候,大量的房产非常大。是否有更复制的方式来复制这些属性?
答案 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工具重命名该属性,它将相应地更改复制代码。)