源类:
public class Post
{
public long ID { get; set; }
[Column(TypeName="nvarchar")]
[Required]
[StringLength(250)]
public string Name { get; set; }
[Column(TypeName="varchar")]
[StringLength(250)]
public string UrlName { get; set; }
[Column(TypeName="ntext")]
public string Excerpt { get; set; }
[Column(TypeName="ntext")]
[Required]
public string Content { get; set; }
public DateTime PostedTime { get; set; }
public DateTime? PublishedTime { get; set; }
public DateTime? LastUpdatedTime { get; set; }
public bool IsPublished { get; set; }
public virtual List<Category> Categories { get; set; }
public virtual List<Comment> Comments { get; set; }
public virtual List<Tag> Tags { get; set; }
}
目的地类
public class Post : Model
{
public long ID { get; set; }
public string Name { get; set; }
public string UrlName { get; set; }
public string Excerpt { get; set; }
public string Content { get; set; }
public DateTime PostedTime { get; set; }
public DateTime LastCommentedTime { get; set; }
public bool IsPublished { get; set; }
public List<Category> Category { get; set; }
public List<Comment> Comments { get; set; }
public List<Tag> Tags { get; set; }
}
我尝试使用EmitMapper相互映射;当从源到desction的映射时,这里是代码示例:
[TestMethod]
public void ShouleMapEntityToModel()
{
Post eP = new Post();
eP.ID = 2;
eP.Comments = new List<Comment>();
eP.Comments.Add(new Comment()
{
ID = 2,
Author = "derek"
});
var mP = eP.Map<Post, mBlog.Core.Models.Post>();
Assert.IsNotNull(mP);
Assert.AreEqual(1, mP.Comments.Count());
}
我得到了一个例外,
测试方法mBlog.Test.EmitMapperTest.ShouleMapEntityToModel抛出异常: System.Exception:在System.Collections.Generic.IList`1 [[mBlog.Core.Models.Post,mBlog.Core,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]中找不到类型[]的构造方法
答案 0 :(得分:1)
我遇到了同样的问题,但我找到了解决方案。不要为目标对象使用列表。如果在mBlog.Core.Models.Post对象中使用简单数组,则应该得到一个很好的填充对象。所以你的目的地类应该是这样的:
public class Post : Model
{
public long ID { get; set; }
public string Name { get; set; }
public string UrlName { get; set; }
public string Excerpt { get; set; }
public string Content { get; set; }
public DateTime PostedTime { get; set; }
public DateTime LastCommentedTime { get; set; }
public bool IsPublished { get; set; }
public Category[] Category { get; set; }
public Comment[] Comments { get; set; }
public Tag[] Tags { get; set; }
}
答案 1 :(得分:0)
这个答案显示了如何处理IEnumerable到IEnumerable:EmitMapper and List
我相信这也适用于这种情况。看看:
这可以创建自定义类,实现接口“ICustomConverterProvider”并将ConvertGeneric添加到“DefaultMapConfig”。
查看EmitMapper的源代码,我发现了一个名为“ArraysConverterProvider”的类,它是从ICollections到Arrays的默认通用转换器。
调整此类中的代码以使用IEnumerable 集合:
class GenericIEnumerableConverterProvider : ICustomConverterProvider { public CustomConverterDescriptor GetCustomConverterDescr( Type from, Type to, MapConfigBaseImpl mappingConfig) { var tFromTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(from); var tToTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(to); if (tFromTypeArgs == null || tToTypeArgs == null || tFromTypeArgs.Length != 1 || tToTypeArgs.Length != 1) { return null; } var tFrom = tFromTypeArgs[0]; var tTo = tToTypeArgs[0]; if (tFrom == tTo && (tFrom.IsValueType || mappingConfig.GetRootMappingOperation(tFrom, tTo).ShallowCopy)) { return new CustomConverterDescriptor { ConversionMethodName = "Convert", ConverterImplementation = typeof(GenericIEnumerableConverter_OneTypes<>), ConverterClassTypeArguments = new[] { tFrom } }; } return new CustomConverterDescriptor { ConversionMethodName = "Convert", ConverterImplementation = typeof(GenericIEnumerableConverter_DifferentTypes<,>), ConverterClassTypeArguments = new[] { tFrom, tTo } }; } } class GenericIEnumerableConverter_DifferentTypes<TFrom, TTo> : ICustomConverter { private Func<TFrom, TTo> _converter; public IEnumerable<TTo> Convert(IEnumerable<TFrom> from, object state) { if (from == null) { return null; } TTo[] result = new TTo[from.Count()]; int idx = 0; foreach (var f in from) { result[idx++] = _converter(f); } return result; } public void Initialize(Type from, Type to, MapConfigBaseImpl mappingConfig) { var staticConverters = mappingConfig.GetStaticConvertersManager() ?? StaticConvertersManager.DefaultInstance; var staticConverterMethod = staticConverters.GetStaticConverter(typeof(TFrom), typeof(TTo)); if (staticConverterMethod != null) { _converter = (Func<TFrom, TTo>)Delegate.CreateDelegate( typeof(Func<TFrom, TTo>), null, staticConverterMethod ); } else { _subMapper = ObjectMapperManager.DefaultInstance.GetMapperImpl(typeof(TFrom), typeof(TTo), mappingConfig); _converter = ConverterBySubmapper; } } ObjectsMapperBaseImpl _subMapper; private TTo ConverterBySubmapper(TFrom from) { return (TTo)_subMapper.Map(from); } } class GenericIEnumerableConverter_OneTypes<T> { public IEnumerable<T> Convert(IEnumerable<T> from, object state) { if (from == null) { return null; } return from; } }
此代码只是一个尽可能少适应的副本 可以应用于具有多层次结构的对象。
您可以使用以下命令使用上述代码:
new DefaultMapConfig().ConvertGeneric( typeof(IEnumerable<>), typeof(IEnumerable<>), new GenericIEnumerableConverterProvider());
这节省了我的一天,我也希望能救你的!呵呵呵