我有一个Fixture模型:
public partial class Fixture
{
public int FixtureId { get; set; }
public string Season { get; set; }
public byte Week { get; set; }
//foreign key
public int AwayTeamId { get; set; }
//navigation properties
public virtual Team AwayTeam { get; set; }
//foreign key
public int HomeTeamId { get; set; }
//navigation properties
public virtual Team HomeTeam { get; set; }
public byte? AwayTeamScore { get; set; }
public byte? HomeTeamScore { get; set; }
}
还有一个Fixture DTO:
public class FixtureDTO
{
public int Id { get; set; }
public string Season { get; set; }
public byte Week { get; set; }
public string AwayTeamName { get; set; }
public string HomeTeamName { get; set; }
public byte? AwayTeamScore { get; set; }
public byte? HomeTeamScore { get; set; }
}
我正在使用AutoMapper进行映射,这是我第一次尝试使用它。这是我的映射:
CreateMap<Fixture, FixtureDTO>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.FixtureId))
.ForMember(dest => dest.AwayTeamName, opt => opt.MapFrom(src => src.AwayTeam.TeamName))
.ForMember(dest => dest.HomeTeamName, opt => opt.MapFrom(src => src.HomeTeam.TeamName));
CreateMap<FixtureDTO, Fixture>();
它可以很好地获取Fixture并将其映射到我用来显示数据的FixtureDTO。但是当我想更新数据并将FixtureDTO传回来将其映射回Fixture时,我收到了一个错误。
public HttpResponseMessage PutFixture(int id, FixtureDTO fixture)
{
if (ModelState.IsValid && id == fixture.Id)
{
//do mapping manually here?
var updated = _repository.UpdateFixture(Mapper.Map<Fixture>(fixture));
return Request.CreateResponse(updated ? HttpStatusCode.OK : HttpStatusCode.NotFound);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
这是我得到的错误:
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
有人可以帮忙吗?
编辑:反向映射:
CreateMap<Fixture, FixtureDTO>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.FixtureId))
.ForMember(dest => dest.AwayTeamName, opt => opt.MapFrom(src => src.AwayTeam.TeamName))
.ForMember(dest => dest.HomeTeamName, opt => opt.MapFrom(src => src.HomeTeam.TeamName));
CreateMap<FixtureDTO, Fixture>()
.ForMember(dest => dest.FixtureId, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.AwayTeam.TeamName, opt => opt.MapFrom(src => src.AwayTeamName))
.ForMember(dest => dest.HomeTeam.TeamName, opt => opt.MapFrom(src => src.HomeTeamName));
答案 0 :(得分:0)
通常,EF在检测到以下情况之一时抛出异常:
Opimistic Concurrency Violation :这通常发生在您尝试编辑的实体被修改时,否则在您加载,编辑和保存它的时间。 (见:Entity Framework: "Store update, insert, or delete statement affected an unexpected number of rows (0).")
错误设置ID :没有为Pks或FK设置ID。当我错误地将Entity的FK设置为一个值并将关联的对象设置为具有不同ID的对象时,我也看到了这样的异常。
由于存储库中的某些代码,很可能会抛出此异常。如果您在存储库中发布代码,我们可能会更好地了解导致异常的原因。
答案 1 :(得分:0)
首先,您需要创建从DTO到实体的反向映射(如果需要,提供自定义成员映射):
Mapper.CreateMap<FixtureDTO, Fixture>();
第二 - 检索,映射和更新现有实体
if (ModelState.IsValid && id == fixture.Id)
{
Fixture entity = _repository.FindById(fixture.Id);
Mapper.Map(fixture, entity); // Use this mapping method!
var updated = _repository.UpdateFixture(entity);
// etc
}
答案 2 :(得分:0)
扩展到@ lazyberezovsky的答案:
这是您可能需要的反向映射的(未经测试)示例:
CreateMap<FixtureDTO, Fixture>()
.ForMember(dest => dest.FixtureId,
opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.AwayTeam,
opt => opt.MapFrom(src => new Team
{
TeamName = src.AwayTeamName
}))
.ForMember(dest => dest.HomeTeam,
opt => opt.MapFrom(src => new Team
{
TeamName = src.HomeTeamName
}));
我过去使用过这种格式并且工作正常,但您也可以为团队创建特定的映射。例如:
CreateMap<string, Team>()....
另外,我假设您正在这样做,但断言您的配置有效。例如:
[Test]
public void AutoMapper_Configuration_IsValid()
{
Mapper.Initialize(m => m.AddProfile<MyProfile>());
Mapper.AssertConfigurationIsValid();
}