c# - 在 ASP.NET MVC 中将 AutoMapper QueryableExtensions 与 Entity Framework 一起使用会导致 "Operation could destabilize the runtime"异常

标签 c# asp.net-mvc automapper

考虑以下代码:

protected override IEnumerable<IListModel> GetListInternal(
    IQueryModel2<Contact> queryModel) {
    /// Causes exception
    return this.Query(queryModel).Project().To<ContactListModel>().AsEnumerable();

    /// Does not cause exception
    return Mapper.Map<IQueryable<Contact>, IEnumerable<ContactListModel>>(this.Query(queryModel)).ToList();
}

当第一行返回时,我得到异常:Operation could destabilize the runtime。当第二行返回时,它工作得很好。据我了解,第二个返回实际上返回一个具体的 IEnumerable<ContactListModel> ,但第一次返回没有。我追加 .AsEnumerable() 没关系, ToArray() , 或 .ToList()对于第一次返回,我只是不断收到异常。因此必须有关于什么的东西 Project()正在返回。无论它返回什么,都可能是 IEnumerable<ContactListModel>因此传递了方法的返回要求,但它是具体对象,当它在管道中进一步处理时会导致异常。

具体来说,此方法返回的集合被传递到 ListWrapper<TEntity>做最后处理的类。当我调用 .Count() 时总是抛出异常关于收藏。

我正在拼命寻求解决投影问题的指导,因为第二次返回效率非常低。从 MiniProfiler 告诉有关使用此特定代码的页面的内容来看,我正在进行 1204 个 SQL 查询,其中有重复项,我认为我们所有人都同意这是一个问题......在此先感谢您的任何建议!

这是Query()IQueryModel2<TEntity>看起来像:

public IQueryable<TEntity> Query(
    IQueryModel2<TEntity> queryModel = null) {
    return this.QueryInternal(queryModel);
}

private IQueryable<TEntity> QueryInternal(
    IQueryModel2<TEntity> queryModel) {
    IQueryable<TEntity> entities = this.Context.Set<TEntity>();

    if (queryModel != null) {
        if (queryModel.Entities != null) {
            entities = queryModel.Entities.AsQueryable();
        }

        if (queryModel.Predicate != null) {
            entities = entities.AsExpandable().Where(queryModel.Predicate);
        }
    }

    return entities;
}

public interface IQueryModel2<TEntity> {
    IEnumerable<TEntity> Entities { get; set; }

    Expression<Func<TEntity, bool>> Predicate { get; set; }

    SearchPostModel Search { get; set; }
}

更新(一)

public sealed class ContactListModel :
    ListModel {
    [Display(Order = 3)]
    public string Email { get; set; }
    [Display(Order = 1)]
    public string Name { get; set; }
    [Display(Order = 2)]
    public string Phone { get; set; }
    [Display(Order = 4)]
    public ContactType ContactType { get; set; }
}

internal sealed class ContactToContactListModel :
    Profile {
    protected override void Configure() {
        base.Configure();

        base.CreateMap<Contact, ContactListModel>()
            .ForMember(
                d => d.Name,
                o => o.MapFrom(
                    s => (s.FirstName + " " + s.LastName)))
            .IgnoreAllUnmapped();
    }
}

更新(二)

public static class AutoMapperExtensions {
    public static IMappingExpression<TSource, TDestination> IgnoreAllUnmapped<TSource, TDestination>(
        this IMappingExpression<TSource, TDestination> expression) {
        if (expression == null) {
            return null;
        }

        return IgnoreAllUnmappedInternal<TSource, TDestination>(expression, typeof(TSource), typeof(TDestination));
    }

    private static IMappingExpression<TSource, TDestination> IgnoreAllUnmappedInternal<TSource, TDestination>(
        IMappingExpression<TSource, TDestination> expression,
        Type sourceType,
        Type destinationType) {
        IEnumerable<string> unmappedProperties = Mapper.GetAllTypeMaps().First(
            m =>
                m.SourceType.Equals(sourceType)
                && m.DestinationType.Equals(destinationType)).GetUnmappedPropertyNames();

        foreach (string unmappedProperty in unmappedProperties) {
            expression.ForMember(unmappedProperty, o => o.Ignore());
        }

        return expression;
    }
}

更新 3

因此,我将项目的程序集加载到 LinqPad 中并重新编写了其中的查询代码。感谢惊人的.Dump() LinqPad 的方法我能够观察到返回的对象到底是什么。所以第一个 return 返回一个 DbQuery<T>默认情况下,第二个返回 IList<T>默认情况下。具有讽刺意味的是,当我在 LinqPad 中调用完全相同的代码序列时,它自己不会抛出异常并且我得到了我期望的 ListWrapper。我真的不确定为什么它在 ASP.NET MVC 中不起作用。虽然我什至不确定这是 ASP.NET 的错,因为它在代码中崩溃了,而代码是另一个程序集中的库项目...

我仍然不知道如何解决这个异常,因为 LinqPad 没有出现这个问题。不确定它是否重要,但我在解决方案的所有项目中都以 .NET 4.5.2 为目标,所以我不确定它是否与此相关?

最佳答案

将 Automapper 升级到 v3.2.0。

这解决了我遇到的确切问题。

关于c# - 在 ASP.NET MVC 中将 AutoMapper QueryableExtensions 与 Entity Framework 一起使用会导致 "Operation could destabilize the runtime"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26172066/

相关文章:

c# - AutoMapper 将源子列表中的对象映射到目标子实体集合中的现有对象

c# - 如何使用 AutoMapper 注册自定义 ObjectMapper

c# - Entity Framework Core LINQ 类属性/方法不能使用包含的属性

c# - 更快的方法来做一个 List<T>.Contains()

c# - 将 MVC 应用程序部署到 Azure 应用程序服务错误 - 未为资源类型注册订阅

c# - 不包含 "Add"的定义

entity-framework - 具有相互导航属性的自动映射器

c# - 重定向运行进程的输出 (Visual C#)

c# - 可以复制 Azure 存储文件共享吗?

c# - 从 MVC Web 项目发送 Apple 推送通知