C# 具有封装子集合的自动映射投影(EF)
我使用Automapper从EF实体映射到视图模型 我现在有了这个实体C# 具有封装子集合的自动映射投影(EF),c#,linq,entity-framework,asp.net-mvc-5,automapper,C#,Linq,Entity Framework,Asp.net Mvc 5,Automapper,我使用Automapper从EF实体映射到视图模型 我现在有了这个实体 public class MenuGroup : IEntity { public int MenuGroupId { get; set; } protected ICollection<MenuGroupItem> _menuGroupItems { get; set; } public IEnumerable<MenuGroupItem> MenuGroupItems {
public class MenuGroup : IEntity
{
public int MenuGroupId { get; set; }
protected ICollection<MenuGroupItem> _menuGroupItems { get; set; }
public IEnumerable<MenuGroupItem> MenuGroupItems { get { return _menuGroupItems; } }
public void AddMenuItem(MenuGroupItem menuGroupItem)
{
_menuGroupItems.Add(menuGroupItem);
}
}
公共类菜单组:IEntity
{
public int MenuGroupId{get;set;}
受保护的ICollection\u菜单组项{get;set;}
公共IEnumerable MenuGroupItems{get{return{MenuGroupItems;}}
public void AddMenuItem(MenuGroupItem MenuGroupItem)
{
_menuGroupItems.Add(menuGroupItem);
}
}
这是一个封装的集合,我按照这里的说明进行操作:
因此,我将其配置为:Sothis.HasMany(x=>x.MenuGroupItems).WithRequired(x=>x.BelongsTo).WillCascadeOnDelete(true)代码>
现在我遇到的问题是,当我尝试使用automapper将我的菜单组映射到viewmodel中时
我运行以下代码:menuGroup=\u context.MenuGroups.Project().To().Single(x=>x.uniqueurfriendlyname==request.uniqueurfriendlyname)代码>
并获取此错误:指定的类型成员“MenuGroupItems”在LINQ to实体中不受支持。仅支持初始值设定项、实体成员和实体导航属性。
现在我可以使用集合,它正确地保存到数据库中,一切都很好。只有当我想在这里使用automapper时,它才会失败
如果我将受保护的ICollection和public IEnumerable替换为:public ICollection MenuGroupItems{get;set;}
它会立即工作,因此问题在于自动映射封装的集合
更新:我也尝试了这个menuGroup=\u context.MenuGroups.Include(x=>x.MenuGroupItems)。其中(x=>x.uniqueurfriendlyName==request.uniqueurfriendlyName)。Project().ToSingleOrDefault()
除了在ToSingleOrDefault中出错之外没有其他区别。您的问题是Automapper无法修改菜单组项,因为没有公共setter
您的解决方案正在将其更改为:
public IEnumerable<MenuGroupItem> MenuGroupItems { get; set; }
public void AddMenuItem(MenuGroupItem menuGroupItem)
{
MenuGroupItems.Add(menuGroupItem);
}
public IEnumerable菜单组项{get;set;}
public void AddMenuItem(MenuGroupItem MenuGroupItem)
{
MenuGroupItems.Add(menuGroupItem);
}
经过进一步调试后,我发现配置文件如下所示
public MenuGroupConfiguration()
{
this.HasMany(x => x.MenuGroupAssigments).WithRequired(x => x.BelongTo).WillCascadeOnDelete(true);
this.HasMany(x => x.MenuGroupItems).WithRequired(x => x.BelongsTo).WillCascadeOnDelete(true);
}
没有被包括在内,导致了现在有意义的错误
我可以添加一个常规提示,如果您不使用自动映射器进行查询,但仍然使用封装的集合,请记住,您必须调用反编译才能使其工作
像这样
var menuGroupsWithType =
_context.MenuGroups.Include(x => x.MenuGroupItems).Include(x => x.MenuGroupAssigments).Where(x => x.MenuGroupAssigments.Any(y => y.AssignToAll == selectedStructureType))
.OrderBy(x => x.Name).Decompile().ToList();
嗯,好吧,但如果我这样做了,那么我的ICollection封装会发生什么呢。我得做一些测试。被迫需要一套是不理想的。还有,为什么它需要一个集合方法。我从该类型投影到该类型。如果需要外部组件进行修改,然后,有一个setterYes是正常的,但我不需要外部组件来修改它,因为我从这个类型投射到它。EF在从数据库结果构建模型时尝试访问它。是的,但是EF有很多特殊代码,以确保它实际使用具有setter的ICollection。然而,Automapper应该只需要从这个类型映射到它,而不需要映射到它。