如何根据类型忽略属性
How to ignore properties based on their type
我正在使用 AutoMapper 将 entity framework 对象复制到另一个相同的数据库。问题是它试图复制查找表。
我试图用 AddGlobalIgnore
和 ShouldMapProperty
排除它们,但它不起作用。 AutoMapper 仍然尝试复制这些属性。
这是我的代码。我想忽略以 "LU"
开头的属性
dynamic newObject= new NewObject();
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.AddGlobalIgnore("LU");
cfg.ShouldMapProperty = p => !p.GetType().ToString().StartsWith("LU");
cfg.ShouldMapField = p => !p.GetType().ToString().StartsWith("LU");
});
IMapper mapper = config.CreateMapper();
newObject = mapper.Map(objectToCopy, objectToCopy.GetType(), newObject.GetType());
我也试过
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.AddGlobalIgnore("LU");
cfg.ShouldMapProperty = p => !p.PropertyType.Name.StartsWith("LU");
cfg.ShouldMapField = p => !p.FieldType.Name.StartsWith("LU");
});
和
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.AddGlobalIgnore("LU");
cfg.ShouldMapProperty = p => !p.Name.StartsWith("LU");
cfg.ShouldMapField = p => !p.Name.StartsWith("LU");
});
我不会说这是最好的(性能或设计方面的)方法,但这是有效的:
public static class AutoExtensions {
public static IMappingExpression Ignore(this IMappingExpression expression, Func<PropertyInfo, bool> filter) {
foreach (var propertyName in expression
.TypeMap
.SourceType
.GetProperties()
.Where(filter)
.Select(x=>x.Name))
{
expression.ForMember(propertyName, behaviour => behaviour.Ignore());
}
return expression;
}
}
您可以像这样配置映射器(对于这些示例 类):
public class Client {
public string LUName { get; set; }
public string Dno { get; set; }
}
public class ClientDTO
{
public string LUName { get; set; }
public string Dno { get; set; }
}
然后像这样测试它:
private static void ConfigAndTestMapper() {
var config = new MapperConfiguration(cfg =>{
cfg.CreateMap(typeof (Client), typeof (ClientDTO))
.Ignore(x => x.Name.StartsWith("LU"));
});
var mapper = config.CreateMapper();
var result = mapper.Map<ClientDTO>(new Client() {LUName = "Name", Dno = "Dno"});
var isIgnored = result.LUName == null;
}
PS:这也很漂亮 "hackish",因为它试图将所有类型的属性映射到那里(readonly/non-public,等等)所以对它持保留态度。
将您的配置创建为单独的配置文件,然后将该配置文件添加到映射器配置中。
class Program
{
static void Main(string[] args)
{
dynamic newObject = new NewObject();
var objectToCopy = new ObjectToCopy();
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MyProfile>();
});
var mapper = config.CreateMapper();
mapper.Map(objectToCopy, newObject);
// newObject.LU_Ignore = "Original value"
// newObject.DoNotIgnore = "New value"
}
}
class MyProfile : Profile
{
protected override void Configure()
{
CreateMissingTypeMaps = true;
ShouldMapProperty = p => !p.Name.StartsWith("LU"); // this is the correct way to get the property name
}
}
class ObjectToCopy
{
public string LU_Ignore { get; set; } = "New value";
public string DoNotIgnore { get; set; } = "New value";
}
class NewObject
{
public string LU_Ignore { get; set; } = "Original value";
public string DoNotIgnore { get; set; } = "Original value";
}
关于如何将配置应用于 Mapper
从 mapper.CreateMapper
调用创建的内容似乎很愚蠢。我正在调查它,看看我是否能找到更多信息,如果我找到任何东西,我会更新这个答案。
我正在使用 AutoMapper 将 entity framework 对象复制到另一个相同的数据库。问题是它试图复制查找表。
我试图用 AddGlobalIgnore
和 ShouldMapProperty
排除它们,但它不起作用。 AutoMapper 仍然尝试复制这些属性。
这是我的代码。我想忽略以 "LU"
开头的属性 dynamic newObject= new NewObject();
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.AddGlobalIgnore("LU");
cfg.ShouldMapProperty = p => !p.GetType().ToString().StartsWith("LU");
cfg.ShouldMapField = p => !p.GetType().ToString().StartsWith("LU");
});
IMapper mapper = config.CreateMapper();
newObject = mapper.Map(objectToCopy, objectToCopy.GetType(), newObject.GetType());
我也试过
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.AddGlobalIgnore("LU");
cfg.ShouldMapProperty = p => !p.PropertyType.Name.StartsWith("LU");
cfg.ShouldMapField = p => !p.FieldType.Name.StartsWith("LU");
});
和
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.AddGlobalIgnore("LU");
cfg.ShouldMapProperty = p => !p.Name.StartsWith("LU");
cfg.ShouldMapField = p => !p.Name.StartsWith("LU");
});
我不会说这是最好的(性能或设计方面的)方法,但这是有效的:
public static class AutoExtensions {
public static IMappingExpression Ignore(this IMappingExpression expression, Func<PropertyInfo, bool> filter) {
foreach (var propertyName in expression
.TypeMap
.SourceType
.GetProperties()
.Where(filter)
.Select(x=>x.Name))
{
expression.ForMember(propertyName, behaviour => behaviour.Ignore());
}
return expression;
}
}
您可以像这样配置映射器(对于这些示例 类):
public class Client {
public string LUName { get; set; }
public string Dno { get; set; }
}
public class ClientDTO
{
public string LUName { get; set; }
public string Dno { get; set; }
}
然后像这样测试它:
private static void ConfigAndTestMapper() {
var config = new MapperConfiguration(cfg =>{
cfg.CreateMap(typeof (Client), typeof (ClientDTO))
.Ignore(x => x.Name.StartsWith("LU"));
});
var mapper = config.CreateMapper();
var result = mapper.Map<ClientDTO>(new Client() {LUName = "Name", Dno = "Dno"});
var isIgnored = result.LUName == null;
}
PS:这也很漂亮 "hackish",因为它试图将所有类型的属性映射到那里(readonly/non-public,等等)所以对它持保留态度。
将您的配置创建为单独的配置文件,然后将该配置文件添加到映射器配置中。
class Program
{
static void Main(string[] args)
{
dynamic newObject = new NewObject();
var objectToCopy = new ObjectToCopy();
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MyProfile>();
});
var mapper = config.CreateMapper();
mapper.Map(objectToCopy, newObject);
// newObject.LU_Ignore = "Original value"
// newObject.DoNotIgnore = "New value"
}
}
class MyProfile : Profile
{
protected override void Configure()
{
CreateMissingTypeMaps = true;
ShouldMapProperty = p => !p.Name.StartsWith("LU"); // this is the correct way to get the property name
}
}
class ObjectToCopy
{
public string LU_Ignore { get; set; } = "New value";
public string DoNotIgnore { get; set; } = "New value";
}
class NewObject
{
public string LU_Ignore { get; set; } = "Original value";
public string DoNotIgnore { get; set; } = "Original value";
}
关于如何将配置应用于 Mapper
从 mapper.CreateMapper
调用创建的内容似乎很愚蠢。我正在调查它,看看我是否能找到更多信息,如果我找到任何东西,我会更新这个答案。