- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 ValueInjecter 来处理将我的 POCO 实体映射到我的 DTO 实体。我一直在用Automapper Simulation作为我的主要映射器。这使我可以像这样简单地编写一个映射:
var entity = GetEntityFromDatabase();
var dto = Mapper.Map<Entity, EntityDTO>(entity);
这一直很好用,直到我需要从我的数据库中获取具有父子关系的实体。问题是我一直在使用的这段代码将递归地遍历所有属性。如果我有一个看起来像这样的 POCO,
public class Entity {
public Guid Id {get; set;}
public Entity Parent {get; set;}
public IEnumerable<Entity> Children {get; set;}
}
我的代码将在无限循环中爆炸,试图映射循环引用。我想继续使用 Automapper Simulation 源作为我的主要映射器,但我一直在想办法解决我的问题。任何帮助将不胜感激!
最佳答案
我相信我通过更改 Automapper Simulation Mapper.cs 文件解决了这个问题。我在递归上实现了一个深度,如果我超过那个深度,我将对象设置为一个已经创建的对象。我确信这可以改进,但是,嘿,它现在有效!
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Omu.ValueInjecter;
namespace MySystem.Services.Mapping
{
// the static mapper class
public static class Mapper
{
private static IList<ObjectContainer> _objects;
//map source to an existing target
public static TTarget Map<TSource, TTarget>(TSource source, TTarget target)
{
target = MapperFactory.GetMapper<TSource, TTarget>().Map(source, target);
return target;
}
//create a new target and map source on it
public static TTarget Map<TSource, TTarget>(TSource source)
{
_objects = new List<ObjectContainer>();
var target = (TTarget)Creator.Create(typeof(TTarget));
var obj = MapperFactory.GetMapper<TSource, TTarget>().Map(source, target);
_objects.Add(new ObjectContainer()
{
original = source,
converted = obj
});
return obj;
}
public static object Map(object source, object target, Type sourceType, Type targetType)
{
target = target ?? Creator.Create(targetType);
var getMapper = typeof(MapperFactory).GetMethod("GetMapper").MakeGenericMethod(sourceType, targetType);
var mapper = getMapper.Invoke(null, null);
var map = mapper.GetType().GetMethod("Map");
var obj = map.Invoke(mapper, new[] { source, target });
_objects.Add(new ObjectContainer()
{
original = source,
converted = obj
});
return obj;
}
public static object MapFinal(object source, object target, Type sourceType, Type targetType)
{
foreach (var obj in _objects)
{
if (source.Equals(obj.original))
{
return obj.converted;
}
}
return null;
}
}
public class ObjectContainer
{
public object original { get; set; }
public object converted { get; set; }
}
public static class MapperFactory
{
private static readonly IDictionary<Type, object> Mappers = new Dictionary<Type, object>();
public static ITypeMapper<TSource, TTarget> GetMapper<TSource, TTarget>()
{
//if we have a specified TypeMapper for <TSource,Target> return it
if (Mappers.ContainsKey(typeof(ITypeMapper<TSource, TTarget>)))
return Mappers[typeof(ITypeMapper<TSource, TTarget>)] as ITypeMapper<TSource, TTarget>;
//if both Source and Target types are Enumerables return new EnumerableTypeMapper<TSource,TTarget>()
if (typeof(TSource).IsEnumerable() && typeof(TTarget).IsEnumerable())
{
return (ITypeMapper<TSource, TTarget>)Activator.CreateInstance(typeof(EnumerableTypeMapper<,>).MakeGenericType(typeof(TSource), typeof(TTarget)));
}
//return the default TypeMapper
return new TypeMapper<TSource, TTarget>();
}
public static void AddMapper<TS, TT>(ITypeMapper<TS, TT> o)
{
Mappers.Add(typeof(ITypeMapper<TS, TT>), o);
}
public static void ClearMappers()
{
Mappers.Clear();
}
}
public interface ITypeMapper<TSource, TTarget>
{
TTarget Map(TSource source, TTarget target);
}
public class TypeMapper<TSource, TTarget> : ITypeMapper<TSource, TTarget>
{
public virtual TTarget Map(TSource source, TTarget target)
{
target.InjectFrom(source);
target.InjectFrom<NullablesToNormal>(source);
target.InjectFrom<NormalToNullables>(source);
target.InjectFrom<IntToEnum>(source);
target.InjectFrom<EnumToInt>(source);
target.InjectFrom<MapperInjection>(source);
return target;
}
}
public class EnumerableTypeMapper<TSource, TTarget> : ITypeMapper<TSource, TTarget>
where TSource : class
where TTarget : class
{
public TTarget Map(TSource source, TTarget target)
{
if (source == null) return null;
var targetArgumentType = typeof(TTarget).GetGenericArguments()[0];
var list = Activator.CreateInstance(typeof(List<>).MakeGenericType(targetArgumentType));
var add = list.GetType().GetMethod("Add");
foreach (var o in source as System.Collections.IEnumerable)
{
var t = Creator.Create(targetArgumentType);
add.Invoke(list, new[] { Mapper.Map(o, t, o.GetType(), targetArgumentType) });
}
return (TTarget)list;
}
}
public static class TypeExtensions
{
//returns true if type is IEnumerable<> or ICollection<>, IList<> ...
public static bool IsEnumerable(this Type type)
{
if (type.IsGenericType)
{
if (type.GetGenericTypeDefinition().GetInterfaces().Contains(typeof(System.Collections.IEnumerable)))
return true;
}
return false;
}
}
public static class Creator
{
public static object Create(Type type)
{
if (type.IsEnumerable())
{
return Activator.CreateInstance(typeof(List<>).MakeGenericType(type.GetGenericArguments()[0]));
}
if (type.IsInterface)
throw new Exception("don't know any implementation of this type: " + type.Name);
return Activator.CreateInstance(type);
}
}
public class MapperInjection : ConventionInjection
{
public const int MaxDepth = 20;
public static int _depth = 0;
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name &&
!c.SourceProp.Type.IsValueType && c.SourceProp.Type != typeof(string) &&
!c.SourceProp.Type.IsGenericType && !c.TargetProp.Type.IsGenericType
||
c.SourceProp.Type.IsEnumerable() &&
c.TargetProp.Type.IsEnumerable();
}
protected override object SetValue(ConventionInfo c)
{
if (c.SourceProp.Value == null)
{
return null;
}
if (_depth > MaxDepth)
return Mapper.MapFinal(c.SourceProp.Value, c.TargetProp.Value, c.SourceProp.Type, c.TargetProp.Type);
_depth++;
object val = Mapper.Map(c.SourceProp.Value, c.TargetProp.Value, c.SourceProp.Type, c.TargetProp.Type);
_depth--;
return val;
}
}
public class EnumToInt : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name &&
c.SourceProp.Type.IsSubclassOf(typeof(Enum)) && c.TargetProp.Type == typeof(int);
}
}
public class IntToEnum : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name &&
c.SourceProp.Type == typeof(int) && c.TargetProp.Type.IsSubclassOf(typeof(Enum));
}
}
//e.g. int? -> int
public class NullablesToNormal : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name &&
Nullable.GetUnderlyingType(c.SourceProp.Type) == c.TargetProp.Type;
}
}
//e.g. int -> int?
public class NormalToNullables : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name &&
c.SourceProp.Type == Nullable.GetUnderlyingType(c.TargetProp.Type);
}
}
关于c# - ValueInjector Stack Overflow 映射实体与父实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13635043/
我正在使用 bootstraptable 并试图让单元格显示溢出的内容但只显示向下(即 overflow-y)。问题是,bootstraptable css 使用 overflow: hidden o
来自文档:溢出: The overflow shorthand CSS property sets what to do when an element's content is too big to
有多个这样命名的问题,但我没有找到一个适用于我的情况,所以我在这里: 在这段代码中: #container:hover { overflow-x: hidden; } #container {
我正在学习 Haskell,但遇到了我没想到的异常“堆栈溢出”。 代码相当简单: type Reals = Double prod :: Reals -> Reals -> Reals prod a
我通读了this question并且没有看到我的问题是否有解决方案。 我创建了一个 CodePen这表明了这个问题。我希望隐藏红色边框左侧和右侧 (overflow-x) 的所有内容,但保持顶部和底
我有一张 bootstrap 4 卡,我想在其中隐藏字幕的溢出(并显示“...”)。我怎样才能实现这个目标?如果可能的话使用纯引导代码... Test object Added by
我今天更新了我的 flutter ,现在堆栈小部件中的溢出参数不再有效。 Flutter 1.22.0-10.0.pre.252 • channel master • https://github.c
使用 border-radius Opera 实际上不会隐藏元素的溢出部分。我已经尝试应用我设法在类似线程中找到的东西,例如定义边框样式或注意使用绝对和相对参数进行定位。但它仍然无法正常工作。 htm
我在固定大小的 div 中有一个表。如果表格溢出 div,我希望滚动条出现。我还想在向下滚动时克隆表格的标题,以便标题持久存在。我遇到的问题是我希望水平滚动条滚动克隆的标题和原始表格,而垂直滚动条
奇怪,我以为 overflow-x 和 overflow-y 都被广泛支持,但后来我才看到它只支持 CSS3( http://reference.sitepoint.com/css/overflow
unsigned long long terms; unsigned long long test; unsigned long long digit = 1; unsigned long long
我有一个案例,我必须使用 overflow-x:scroll; 水平显示内容。 现在在这个Fiddle第一个 block 有 overflow-y:scroll; 提供滚动,用户可以滚动内容。在第二个
您好,我正在尝试只使用 overflow-x 而不是 overflow-y 结构是这样的 Head1 feild1
我有一个正在运行的计划作业,我想计算过去 30 天的时间。为此,我收到一条警告,表示在表达式中检测到数字溢出。我怎样才能安全地给予 30 天? @Override @Scheduled(cro
我有一个父级,它有多个子级,当父级宽度溢出时,我喜欢显示水平滚动条。 我不想使用“display:inline-block”属性,因为它们之间会产生空白。 这是我的尝试: .parent{ wid
我正在为导航栏编写一些 CSS,我需要为下拉菜单使用 max-height 和 overflow-y: scroll 以便确保它适合页面。但是,每当我将 overflow-y 属性设置为滚动时,它似乎
这是我的问题。我有一个旋转木马,它也像菜单一样。当选项卡的数量高于浏览器可用的宽度空间时,将出现轮播控件。一切正常。但我还在每个选项卡上添加了一个下拉菜单,这就是问题所在。如果我设置 overflow
这个问题在这里已经有了答案: CSS overflow-x: visible; and overflow-y: hidden; causing scrollbar issue (10 个答案) 关
这个问题在这里已经有了答案: How do you keep parents of floated elements from collapsing? [duplicate] (15 个答案) W
这是一个代码片段: div.one { width: 98%; border: 5px solid black; overflow-x: visible; overflow-y: hi
我是一名优秀的程序员,十分优秀!