gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 15:50:12 25 4
gpt4 key购买 nike

考虑以下代码:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com