C# 具有封装子集合的自动映射投影(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 {

我使用Automapper从EF实体映射到视图模型

我现在有了这个实体

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);
}
}
这是一个封装的集合,我按照这里的说明进行操作:

因此,我将其配置为:So
this.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应该只需要从这个类型映射到它,而不需要映射到它。