Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用AutoMapper重新使用集合属性中的目标实例_C#_Entity Framework_Automapper - Fatal编程技术网

C# 使用AutoMapper重新使用集合属性中的目标实例

C# 使用AutoMapper重新使用集合属性中的目标实例,c#,entity-framework,automapper,C#,Entity Framework,Automapper,我有一个编辑模型和一个EF实体,我想使用AutoMapper用编辑模型中的数据更新实体。这非常有效: // The classes involved public class FooEditModel { public Guid Id { get; set; } public string FooProp { get; set; } } public class FooEntity { public Guid Id { get; set; } public st

我有一个编辑模型和一个EF实体,我想使用AutoMapper用编辑模型中的数据更新实体。这非常有效:

// The classes involved
public class FooEditModel {
    public Guid Id { get; set; }
    public string FooProp { get; set; }
}

public class FooEntity {
    public Guid Id { get; set; }
    public string FooProp { get; set; }
}

// Mapper configuration
cfg.CreateMap<FooEditModel, FooEntity>();

// Actual usage
var entity = _dbContext.Foos
    .Where(e => e.Id == id) // id is a route param
    .Single();
_mapper.Map(editModel, entity); // editModel is populated by model binding
_dbContext.SaveChanges();
现在,它没有更新
footentity
以及所有相关的
BarEntity
s,而是给我一个
InvalidOperationException
,并显示以下消息:

InvalidOperationException:无法跟踪实体类型“BarEntity”的实例,因为已在跟踪具有相同密钥的此类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置键(即,如果为键属性指定了其类型的默认值),则将创建唯一的临时键值。如果要显式设置新实体的键值,请确保它们不会与现有实体或为其他新实体生成的临时值冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文

如何配置AutoMapper,使映射程序可以重新使用现有集合中的对象,而不是尝试替换它们?

你应该了解引擎盖下发生了什么。AutoMapper是一个简单的工具,它使用反射来避免逐行重写属性。尽管如此,它还是在不使用集合的情况下不时创建新对象(如您使用集合的示例中)。映射程序并没有创建任何东西—它只是重写属性。如果您添加集合,他将通过创建新集合来从editModel映射新集合来处理此问题

这会造成这样一种情况:在DataContext上,您已经实例化了Bar类型的对象,而mapper正在创建一个新的对象,这会导致冲突


正如Ivan Stoev所说,您可以使用Automapper.Collection来处理这种情况(虽然我从未使用过它,但它可能解决了这个问题)

看看package.Automapper.Collection确实解决了这个问题-谢谢(您和Ivan)!起初,我在让它工作时遇到了一些麻烦,但结果证明这主要是因为它对配置提出了一些要求,这些要求在使用AutoMapper.Attributes时很难满足,所以我放弃了后者,现在它可以工作了。
// classes
pulic class FooEditModel {
    public Guid Id { get; set; }
    public IReadOnlyCollection<BarEditModel> Bars { get; set; }
}
public class BarEditModel {
    public Guid Id { get; set; }
    public string BarProp { get; set; }
}

public class FooEntity {
    public Guid Id { get; set; }
    public IReadOnlyCollection<BarEntity> Bars { get; set; }
}
public class BarEntity {
    public string BarProp { get; set; }
}

// mapper config
cfg.CreateMap<FooEditModel, FooEntity>();
cfg.CreateMap<BarEditModel, BarEntity>();

// usage
var entity = _dbContext.Foos
    .Include(f => f.Bars)
    .Where(f => f.id == id)
    .Single();

_mapper.Map(editModel, entity);

_dbContext.SaveChanges();