具有封装子集合的自动映射投影(EF)

时间:2014-11-06 21:06:05

标签: 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 { get { return _menuGroupItems; } }

    public void AddMenuItem(MenuGroupItem menuGroupItem)
    {
        _menuGroupItems.Add(menuGroupItem);
    }
}

这是一个封装的集合,我按照这里的说明进行了这项工作:http://lostechies.com/jimmybogard/2014/05/09/missing-ef-feature-workarounds-encapsulated-collections/

所以我将其配置为this.HasMany(x => x.MenuGroupItems).WithRequired(x => x.BelongsTo).WillCascadeOnDelete(true);

现在我遇到的问题是当我尝试使用automapper将MenuGroup映射到视图模型时。

我运行此代码:menuGroup = _context.MenuGroups.Project().To<MenuGroupEditModel>().Single(x => x.UniqueUrlFriendlyName == request.UniqueUrlFriendlyName);

并收到此错误:The specified type member 'MenuGroupItems' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.


现在我可以使用该集合,它可以正确地保存到数据库中,并且一切都很好,只有当我想在这里使用者自动化它才会失败。

如果我用简单的public ICollection<MenuGroupItem> MenuGroupItems { get; set; }替换受保护的ICollection和公共IEnumerable,它就可以正常工作,所以问题在于我使用封装的集合进行自动化。


更新:我还尝试了这个menuGroup = _context.MenuGroups.Include(x => x.MenuGroupItems).Where(x => x.UniqueUrlFriendlyName == request.UniqueUrlFriendlyName).Project().ToSingleOrDefault<MenuGroupEditModel>();,除了在ToSingleOrDefault中出错之外没有区别。

2 个答案:

答案 0 :(得分:1)

您的问题是Automapper无法修改MenuGroupItems,因为没有公共设置器。

您的解决方案正在将其更改为:

public IEnumerable<MenuGroupItem> MenuGroupItems { get; set; }

public void AddMenuItem(MenuGroupItem menuGroupItem)
{
    MenuGroupItems.Add(menuGroupItem);
}

答案 1 :(得分:0)

经过一些调试后,我发现Config文件看起来像这样

    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();