C# DbContext、EF6和Automapper

C# DbContext、EF6和Automapper,c#,entity-framework,automapper,C#,Entity Framework,Automapper,在MVC项目中,我使用Autommaper链接ViewModel和实体(EF6)。我正在寻找一种自动化,所以我正在尝试使用Automapper管理DBContext。但是,环境似乎松动了他的变化。您知道为什么pContext会在两个断点之间进行松散更改吗 断点1:pContext.ChangeTracker.HasChanges()=true 断点2:pContext.ChangeTracker.HasChanges()=false public void保存地址(AddressViewMode

在MVC项目中,我使用Autommaper链接ViewModel和实体(EF6)。我正在寻找一种自动化,所以我正在尝试使用Automapper管理DBContext。但是,环境似乎松动了他的变化。您知道为什么pContext会在两个断点之间进行松散更改吗

断点1:pContext.ChangeTracker.HasChanges()=true

断点2:pContext.ChangeTracker.HasChanges()=false

public void保存地址(AddressViewModel pModel)
{
OpenTransaction();
CreateMapAddressModel(上下文);
var lAddress=Mapper.Map(pModel);
//新数据提供程序(上下文)。插入(LadAddress);
CloseTransaction();
}
public void CreateMapAddressModel(MyModel pContext)
{
if(Mapper.FindTypeMapFor(typeof(AddressViewModel),typeof(Address)).IsNull()
{
Mapper.CreateMap().IgnoreAllNonExisting()
.ConstructUsing((AddressViewModels)=>pContext.Set().Find(s.Id)??pContext.Set().Create())
.AfterMap((src,dest)=>dest.ApplicationUser=pContext.Set().FirstOrDefault(x=>x.Id==src.applicationSerid))
.AfterMap((src,dest)=>pContext.Entry(dest).State=dest.Id==Guid.Empty?EntityState.Added:EntityState.Modified)
.AfterMap((src,dest)=>
{
if(dest.Id==Guid.Empty)
{
//pContext.Set().Add(dest);
System.Diagnostics.Debug.WriteLine(pContext.Entry(dest.State);//Value=Added

System.Diagnostics.Debug.WriteLine(pContext.ChangeTracker.HasChanges());//Value=True//我真的不知道。但是,当您更改上下文的状态(pContext.Entry(dest.state=…)时,似乎您正在使用AutoMapper来实现它的目的。我认为在执行映射时只应设置目的地的对象状态。“当您需要在映射操作之前/之后输入上下文信息时,后一种配置很有用。”这意味着AfterMap应用于提供上下文信息,而不是更改“外部”对象。我想我发现了问题。你是对的,我将停止在Automapper中使用上下文。发送到Automapper匿名函数的上下文将不会更新,因为它将仅在创建映射时设置。如果添加Mapper.Reset();一开始。在Breakpint 1和2之间,pContext是不同的。您可能想看看这个项目,它包含视图模型和实体之间映射的详细信息,如果它使用ValueInjector而不是AutoMapper来实现,但实现可能会引导您走向正确的方向。感谢您的链接。一个月后在电脑之外,我又回到了我的项目。现在,我在地图动作上设置了afterMap表达式,而不是在CreateMap动作上,它工作了。我可以研究这个项目并找到一个更好的方法。我真的不知道。但是当你改变上下文的状态时,你似乎在用AutoMaper做它不想做的事情(pContext.Entry(dest.State=…)。我认为在执行映射时只应设置目标的对象状态。“当您需要在映射操作之前/之后输入上下文信息时,后一种配置很有用。”这意味着AfterMap应用于提供上下文信息,而不是更改“外部”对象。我想我发现了问题。你是对的,我将停止在Automapper中使用上下文。发送到Automapper匿名函数的上下文将不会更新,因为它将仅在创建映射时设置。如果添加Mapper.Reset();一开始。在Breakpint 1和2之间,pContext是不同的。您可能想看看这个项目,它包含视图模型和实体之间映射的详细信息,如果它使用ValueInjector而不是AutoMapper来实现,但实现可能会引导您走向正确的方向。感谢您的链接。一个月后离开电脑后,我又回到了我的项目中。现在,我在Map动作上设置了afterMap表达式,而不是在CreateMap动作上设置了afterMap表达式,这很有效。我可以研究这个项目并找到更好的方法。
    public void SaveAddress(AddressViewModel pModel)
    {
        OpenTransaction();

        CreateMapAddressModel(Context);
        var lAddress = Mapper.Map<AddressViewModel, Address>(pModel);
        //new DataProvider<Address>(Context).Insert(lAddress);

        CloseTransaction();
    }

    public void CreateMapAddressModel(MyModel pContext)
    {
        if (Mapper.FindTypeMapFor(typeof(AddressViewModel), typeof(Address)).IsNull())
        {
            Mapper.CreateMap<AddressViewModel, Address>().IgnoreAllNonExisting()
                .ConstructUsing((AddressViewModel s) => pContext.Set<Address>().Find(s.Id) ?? pContext.Set<Address>().Create())
                .AfterMap((src, dest) => dest.ApplicationUser = pContext.Set<ApplicationUser>().FirstOrDefault(x => x.Id == src.ApplicationUserId))
                .AfterMap((src, dest) => pContext.Entry(dest).State = dest.Id == Guid.Empty ? EntityState.Added : EntityState.Modified)
                .AfterMap((src, dest) =>
                {
                    if (dest.Id == Guid.Empty)
                    {
                        //pContext.Set<Address>().Add(dest);
                        System.Diagnostics.Debug.WriteLine(pContext.Entry(dest).State);//Value = Added
                        System.Diagnostics.Debug.WriteLine(pContext.ChangeTracker.HasChanges());//Value = True//<-- Breakpoint 1
                    }
                })
                ;
        }
    }//<-- Breakpoint 2