我正在使用EF 4.1 Code First。我有一个实体,用这样的属性定义:
public class Publication
{
// other stuff
public virtual MailoutTemplate Template { get; set; }
}
我使用流畅的样式配置了这个外键:
modelBuilder.Entity<Publication>()
.HasOptional(p => p.Template)
.WithMany()
.Map(p => p.MapKey("MailoutTemplateID"));
我有一个MVC表单处理程序,其中包含一些代码如下:
public void Handle(PublicationEditViewModel publicationEditViewModel)
{
Publication publication = Mapper.Map<PublicationEditViewModel, Publication>(publicationEditViewModel);
publication.Template = _mailoutTemplateRepository.Get(publicationEditViewModel.Template.Id);
if (publication.Id == 0)
{
_publicationRepository.Add(publication);
}
else
{
_publicationRepository.Update(publication);
}
_unitOfWork.Commit();
}
在这种情况下,我们正在更新现有的Publication实体,因此我们将通过else路径。当_unitOfWork.Commit()触发时,UPDATE将发送到我在SQL事件探查器和Intellitrace中可以看到的数据库,但它不会在更新中包含MailoutTemplateID。
让它真正更新模板的诀窍是什么?
存储库代码:
public virtual void Update(TEntity entity)
{
_dataContext.Entry(entity).State = EntityState.Modified;
}
public virtual TEntity Get(int id)
{
return _dbSet.Find(id);
}
UnitOfWork代码:
public void Commit()
{
_dbContext.SaveChanges();
}
答案 0 :(得分:1)
取决于您的存储库代码。 :)如果您在上下文跟踪发布时设置publication.Template,我希望它能够正常工作。当您断开连接然后附加(具有导航属性但没有显式FK属性的场景)时,我猜测上下文没有足够的信息来计算调用SaveChanges时的详细信息。我做了一些实验。 1)进行集成测试,查询pub并将其附加到上下文,然后添加模板,然后保存。 2)在Publicaction类上粘贴一个MailOutTemplateId属性,看它是否有效。不建议#2作为解决方案,只是作为一种行为方式。我很想做这个实验,但还有其他一些我需要做的工作。;)
答案 1 :(得分:0)
我找到了让它发挥作用的方法。我最初不想做Get()(除了额外的数据库命中)的原因是我不能用AutoMapper魔法来获取这些值:
Publication publication = Mapper.Map<PublicationEditViewModel, Publication>(publicationEditViewModel);
但是,我找到了另一种方法来做同样的事情而不使用返回值,所以我更新了我的方法,这样就可以了:
public void Handle(PublicationEditViewModel publicationEditViewModel)
{
Publication publication = _publicationRepository.Get(publicationEditViewModel.Id);
_mappingEngine.Map(publicationEditViewModel, publication);
// publication = Mapper.Map<PublicationEditViewModel, Publication>(publicationEditViewModel);
publication.Template = _mailoutTemplateRepository.Get(publicationEditViewModel.Template.Id);
if (publication.Id == 0)
{
_publicationRepository.Add(publication);
}
else
{
_publicationRepository.Update(publication);
}
_unitOfWork.Commit();
}
我现在正在将一个IMappingEngine注入到类中,并通过StructureMap将其连接起来,如下所示:
For<IMappingEngine>().Use(() => Mapper.Engine);
有关详情,请查看Jimmy's AutoMapper and IOC post。