在我的数据库中,我有一个包含2个明细表的基表,该基表中的每个记录将只有一个明细记录。我正在尝试将这3个表映射到从共享基本域模型继承的两个域模型。在EntityFramework中,这通常称为按类型继承表,但在EntityFrameworkCore中未实现。
我的dto模型看起来像
public class SourceBase
{
public int Id {get;set;}
public string Value {get;set;}
public SourceA A {get;set;}
public SourceB B {get;set;}
}
public class SourceA
{
public string ValueA {get;set;}
}
public class SourceB
{
public string ValueB {get;set;}
}
我想要的域模型如下
public class TargetBase
{
public int Id {get;set;}
public string Value {get;set;}
}
public class TargetA : TargetBase
{
public string ValueA {get;set;}
}
public class TargetB : TargetBase
{
public string ValueB {get;set;}
}
我如何设置映射以完成此操作?
我最成功的尝试是:
CreateMap<SourceBase, TargetBase>().ConvertUsing<CustomTypeConverter>();
CreateMap<SourceA, TargetA>();
CreateMap<SourceB, TargetB>();
使用CustomTypeConverter:
public class CustomTypeConverter : ITypeConverter<SourceBase, TargetBase>
{
public TargetBase Convert(SourceBase source, TargetBase destination, ResolutionContext context)
{
if (source.A == null)
{
return context.Mapper.Map<SourceB, TargetB>(source.B);
}
else if (source.B == null)
{
return context.Mapper.Map<SourceA, TargetA>(source.A);
}
return null;
}
}
可以正确地给我TargetA或TargetB类型,但是没有TargetBase值被映射。
答案 0 :(得分:1)
为此找到的最简单的方法是使用ConstructUsing
和AfterMap
以避免递归:
public class Program
{
public static void Main()
{
AutoMapper.Mapper.Reset();
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.CreateMap<SourceBase, TargetBase>().ConstructUsing(x => Convert(x)).AfterMap(Transform);
cfg.CreateMap<SourceA, TargetA>();
cfg.CreateMap<SourceB, TargetB>();
});
var src = new SourceBase
{
Id = 3,
Value = "Asd",
A = new SourceA
{
ValueA = "Qwe"
}
};
var a = AutoMapper.Mapper.Map<SourceBase, TargetBase>(src);
a.Dump(); // Code for LinqPad to show the result
}
public static TargetBase Convert(SourceBase source)
{
if (source.A == null)
{
return new TargetB();
}
else if (source.B == null)
{
return new TargetA();
}
return null;
}
public static void Transform(SourceBase source, TargetBase target)
{
if (source.A == null)
{
AutoMapper.Mapper.Map<SourceB, TargetB>(source.B, (TargetB)target);
}
else if (source.B == null)
{
AutoMapper.Mapper.Map<SourceA, TargetA>(source.A, (TargetA)target);
}
}
}
public class SourceBase
{
public int Id {get;set;}
public string Value {get;set;}
public SourceA A {get;set;}
public SourceB B {get;set;}
}
public class SourceA
{
public string ValueA {get;set;}
}
public class SourceB
{
public string ValueB {get;set;}
}
public class TargetBase
{
public int Id {get;set;}
public string Value {get;set;}
}
public class TargetA : TargetBase
{
public string ValueA {get;set;}
}
public class TargetB : TargetBase
{
public string ValueB {get;set;}
}
您显然可以将转换方法放入自己的类中
答案 1 :(得分:0)
我敢肯定还有其他方法,但是它几乎可以像您尝试的那样工作。
ActiveSheet.PageSetup.BlackAndWhite = False
ActiveWindow.SelectedSheets.PrintOut Copies:=1, ActivePrinter:="\\printer\printer1", Collate:=True, _
IgnorePrintAreas:=False
Sheets("REPORT").Select
如果您遵循the naming convention或使用an extension method,则不需要MapFroms。
答案 2 :(得分:0)
与卢西安的答案非常相似。我更喜欢这样做,因为它可以明确表明它选择了特定的派生类映射,但实际上是相同的答案。
<input name="IsEmptyString" type="hidden"/>