[英]AutoMapper: Mapping between the two collections with 'Ignore'
我正在使用AutoMapper在兩個集合之間進行映射。 我看到的是Ignore
在這種情況下沒有按預期工作。 我期待的可以在方法AutoMapperIgnore_TwoObjectMappedWithIgnoreId_SameWithUnchangedIdAndNewPrice()
看到。 在其他兩個測試方法中,盡管忽略了Id
但是集合中的每個對象都會再次創建,原因是原始值將丟失。 有可能使用UseDestinationValue
,但我認為這只對集合所屬的類有意義。 如何在集合中使用“ Ignore
”選項?
[TestClass]
public class AutoMapperTests
{
private readonly IEnumerable<Dto> _testDtos;
private readonly IEnumerable<Entity> _testEntities;
public AutoMapperTests()
{
_testDtos = new List<Dto>
{
new Dto()
{
Id = 0,
Fk_Id = 8,
Price = 350000
}
};
_testEntities = new List<Entity>
{
new Entity()
{
Id = 8,
Price = 68000
}
,
new Entity()
{
Id = 6,
Price = 350000
}
};
}
[TestInitialize]
public void TestInitialize()
{
Mapper.Reset();
}
[TestMethod]
public void AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntityIgnoreId_SameWithUnchangedIdAndNewPrice()
{
//Assign
Mapper.CreateMap<Dto, Entity>()
.ForMember(destination => destination.Id, opt => opt.Ignore());
AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntity_SameWithUnchangedIdAndNewPrice(true);
}
[TestMethod]
public void AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntityUseDestinationtValueForId_SameWithUnchangedIdAndNewPrice()
{
//Assign
Mapper.CreateMap<Dto, Entity>()
.ForMember(destination => destination.Id, opt => opt.UseDestinationValue());
AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntity_SameWithUnchangedIdAndNewPrice(true);
}
private void AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntity_SameWithUnchangedIdAndNewPrice(bool isExceptedSame)
{
//Assign
var exceptedPrice = _testDtos.First().Price;
//Act
IEnumerable<Entity> foundEntities = _testEntities.Join(_testDtos, e => e.Id, e => e.Fk_Id, (entity, dto) => entity).ToList();
Entity entityBeforeMapping = foundEntities.First();
Mapper.Map(_testDtos, foundEntities);
Entity entityAfterMapping = foundEntities.First();
//Assert
if (isExceptedSame)
{
Assert.AreSame(entityBeforeMapping, entityAfterMapping);
}
Assert.AreEqual(entityBeforeMapping.Id, entityAfterMapping.Id);
Assert.AreEqual(exceptedPrice, entityAfterMapping.Price);
}
[TestMethod]
public void AutoMapperIgnore_TwoObjectMappedWithIgnoreId_SameWithUnchangedIdAndNewPrice()
{
//Assign
Mapper.CreateMap<Dto, Entity>()
.ForMember(destination => destination.Id, opt => opt.Ignore());
var testDto = new Dto()
{
Id = 0,
Fk_Id = 8,
Price = 350000
};
var testEntity = new Entity()
{
Id = 8,
Price = 68000
};
var exceptedPrice = testDto.Price;
//Act
Entity entityBeforeMapping = testEntity;
Mapper.Map(testDto, testEntity);
Entity entityAfterMapping = testEntity;
//Assert
Assert.AreSame(entityBeforeMapping, entityAfterMapping);
Assert.AreEqual(entityBeforeMapping.Id, entityAfterMapping.Id);
Assert.AreEqual(exceptedPrice, entityAfterMapping.Price);
}
internal class Dto
{
public int Id { get; set; }
public int Fk_Id { get; set; }
public Single? Price { get; set; }
}
internal class Entity
{
public int Id { get; set; }
public Single? Price { get; set; }
}
}
正如@Stef所提到的,你必須單獨映射集合中的每個條目,就像這樣
_testEntities.Join(_testDtos, e => e.Id, e => e.Fk_Id, (entity, dto) => Mapper.Map(dto,entity));
這里有完整的功能示例:
[TestClass]
public class AutoMapperTests
{
private readonly IEnumerable<Dto> _testDtos;
private readonly IEnumerable<Entity> _testEntities;
public AutoMapperTests()
{
_testDtos = new List<Dto>
{
new Dto()
{
Id = 0,
Fk_Id = 8,
Price = 350000
}
};
_testEntities = new List<Entity>
{
new Entity()
{
Id = 8,
Price = 68000
}
,
new Entity()
{
Id = 6,
Price = 350000
}
};
}
[TestInitialize]
public void TestInitialize()
{
Mapper.Reset();
}
[TestMethod]
public void AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntityIgnoreId_SameWithUnchangedIdAndNewPrice()
{
//Assign
Mapper.CreateMap<Dto, Entity>()
.ForMember(destination => destination.Id, opt => opt.Ignore());
AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntity_SameWithUnchangedIdAndNewPrice(true);
}
[TestMethod]
public void AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntityUseDestinationtValueForId_SameWithUnchangedIdAndNewPrice()
{
//Assign
Mapper.CreateMap<Dto, Entity>()
.ForMember(destination => destination.Id, opt => opt.UseDestinationValue());
AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntity_SameWithUnchangedIdAndNewPrice(true);
}
private void AutoMapperIgnore_TwoCollectionsWithOneCommonElementMappedFromDtoToEntity_SameWithUnchangedIdAndNewPrice(bool isExceptedSame)
{
//Assign
var exceptedPrice = _testDtos.First().Price;
//Act
Entity entityBeforeMapping = _testEntities.First(testEntity => testEntity.Id == _testEntities.First().Id);
IEnumerable<Entity> foundEntities = _testEntities.Join(_testDtos, e => e.Id, e => e.Fk_Id, (entity, dto) => Mapper.Map(dto,entity));
Entity entityAfterMapping = foundEntities.First();
//Assert
if (isExceptedSame)
{
Assert.AreSame(entityBeforeMapping, entityAfterMapping);
}
Assert.AreEqual(entityBeforeMapping.Id, entityAfterMapping.Id);
Assert.AreEqual(exceptedPrice, entityAfterMapping.Price);
}
[TestMethod]
public void AutoMapperIgnore_TwoObjectMappedWithIgnoreId_SameWithUnchangedIdAndNewPrice()
{
//Assign
Mapper.CreateMap<Dto, Entity>()
.ForMember(destination => destination.Id, opt => opt.Ignore());
var testDto = new Dto()
{
Id = 0,
Fk_Id = 8,
Price = 350000
};
var testEntity = new Entity()
{
Id = 8,
Price = 68000
};
var exceptedPrice = testDto.Price;
//Act
Entity entityBeforeMapping = testEntity;
Mapper.Map(testDto, testEntity);
Entity entityAfterMapping = testEntity;
//Assert
Assert.AreSame(entityBeforeMapping, entityAfterMapping);
Assert.AreEqual(entityBeforeMapping.Id, entityAfterMapping.Id);
Assert.AreEqual(exceptedPrice, entityAfterMapping.Price);
}
internal class Dto
{
public int Id { get; set; }
public int Fk_Id { get; set; }
public Single? Price { get; set; }
}
internal class Entity
{
public int Id { get; set; }
public Single? Price { get; set; }
}
}
我做了一些測試並確認了你的問題。
映射IEnumerable列表時,AutoMapper會創建一個新的IEnumerable列表,該列表僅包含您定義要映射的屬性,因此只有“Price”。
為了將Dto映射到實體,您需要定義一個使它們唯一的屬性,如PrimaryKey。
class Dto
{
public long PrimaryKey { get; set; }
public int Id { get; set; }
public int Fk_Id { get; set; }
public Single? Price { get; set; }
}
class Entity
{
public long PrimaryKey { get; set; }
public int Id { get; set; }
public Single? Price { get; set; }
}
將列表映射到列表可以這樣做:
// Update entities in original list
foreach (var d in _testDtos)
{
foreach (var e in _testEntities)
{
if (e.PrimaryKey == d.PrimaryKey)
{
Mapper.Map(d, e);
}
}
}
或更多linq友好:
// Create a new list
var foundEntities = _testEntities.Join(_testDtos, e => e.PrimaryKey, d => d.PrimaryKey, (entity, dto) => Mapper.Map<Entity>(dto)).ToList();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.