C# 类型为';的未处理异常;System.StackOverflowException';将AutoMapper与多对一相关实体一起使用
修复此错误后:我收到错误: 无法计算表达式,因为当前线程处于堆栈溢出状态。 这里是我最初得到错误的地方(如您所见,它与第一个错误是同一行): 更新: 当我将ignore语句添加到我的C# 类型为';的未处理异常;System.StackOverflowException';将AutoMapper与多对一相关实体一起使用,c#,asp.net-mvc,viewmodel,automapper,stack-overflow,C#,Asp.net Mvc,Viewmodel,Automapper,Stack Overflow,修复此错误后:我收到错误: 无法计算表达式,因为当前线程处于堆栈溢出状态。 这里是我最初得到错误的地方(如您所见,它与第一个错误是同一行): 更新: 当我将ignore语句添加到我的CreateMap()中时声明: CreateMap<Pages, PagesViewModel>() .ForMember(m => m.PageTypes, x => x.Ignore()) .ForMember(m => m.Sit
CreateMap()中时代码>声明:
CreateMap<Pages, PagesViewModel>()
.ForMember(m => m.PageTypes, x => x.Ignore())
.ForMember(m => m.SiteMap, x => x.Ignore())
.ForMember(m => m.Row, x => x.Ignore())
.ForMember(m => m.Tracks, x => x.Ignore());
该错误执行以下操作之一(所有三种情况都已发生,并且很难重现特定的错误):
第一个是应用程序一直在运行并且
最终超时李>
程序“[5256]iisexpress.exe”已退出,代码为-2147023895(0x800703e9)李>
转到代码的另一部分(my PagesViewModel)
(更新):
private string PagesURL;
[Required]
[Display(Name = "Page URL")]
[DataType(DataType.Url)]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long and no longer than {1} characters.", MinimumLength = 2)]
public string pagesURL
{
get { return PagesURL; }
set { PagesURL = HttpUtility.UrlEncode(value); }
}
// disable proxy creation just for the duration of query
_context.Configuration.ProxyCreationEnabled = false;
// do the query, map, go crazy!
// enable proxy again. or if your context goes out of scope after this call, then you can ignore re-enabling.
_context.Configuration.ProxyCreationEnabled = true;
当第三个线程出现时,我得到了相同的错误:无法计算表达式,因为当前线程处于堆栈溢出状态。
我已尝试通过尝试以下操作来分离代码,以了解它在何处以及为什么这样做:
List<Pages> getPages = db.Pages.ToList();
List<Pages> getPagesOrdered = getPages.OrderBy(o => o.pageOrder).ToList();
List<PagesViewModel> convertPages = new List<PagesViewModel>();
foreach (Pages item in getPages)
{
PagesViewModel pagesViewModel = new PagesViewModel();
pagesViewModel.pageDescription = item.pageDescription;
//...loops through all other properties
convertPages.Add(pagesViewModel);
}
List getPages=db.Pages.ToList();
List getPagesOrdered=getPages.OrderBy(o=>o.pageOrder.ToList();
List convertPages=新列表();
foreach(getPages中的Pages项)
{
PagesViewModel PagesViewModel=新的PagesViewModel();
pagesViewModel.pageDescription=item.pageDescription;
//…循环所有其他属性
convertPages.Add(pagesViewModel);
}
它从数据库上下文中获取所有页面,对其进行排序并声明PagesViewModel精细,但当它进入for循环时,它声明PagesViewModel变量精细,然后紧接着,甚至在它跳到PagesViewModel.pageDescription=item.pageDescription之前代码>行应用程序崩溃程序“[5176]iisexpress.exe”已退出,代码为0(0x0)。
酋长先生,在我顶部链接的答案中,我建议是我的模型如何相互连接导致了这个问题。例如,PagesViewModel连接到公共虚拟页面类型viewmodel页面类型{get;set;}
并且PagesViewModel连接回PagesViewModel公共ICollection页面{get;set;}
我的模型需要连接这些变量,并且在没有自动映射器的情况下工作正常(除了我试图手动设置每个变量,这会导致应用程序崩溃)。我被困住了,希望能有一些见解
更新:
private string PagesURL;
[Required]
[Display(Name = "Page URL")]
[DataType(DataType.Url)]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long and no longer than {1} characters.", MinimumLength = 2)]
public string pagesURL
{
get { return PagesURL; }
set { PagesURL = HttpUtility.UrlEncode(value); }
}
// disable proxy creation just for the duration of query
_context.Configuration.ProxyCreationEnabled = false;
// do the query, map, go crazy!
// enable proxy again. or if your context goes out of scope after this call, then you can ignore re-enabling.
_context.Configuration.ProxyCreationEnabled = true;
来到这里后:我的一位同事给我们弄到了AutoMapper的符号,这样我们就可以追踪到源代码。我们添加了一个跟踪断点来输出导致问题的实际原因。以下是它几百次的输出:
从“页面”、“页面类型”到“页面视图模型”、“页面类型”
所以酋长先生的预测是正确的。现在,我不知道如何解决这个问题
这是PageViewModel链接到PageTypes视图模型的地方:public虚拟PageTypeViewModel PageTypes{get;set;}
,然后在PageTypesViewModel中链接到PageViewModel:public ICollection页面{get;set;}
这就是EF6生成我的模型的方式。我先做了这个模型
我可能忘了包括一些重要信息,所以如果遗漏了什么,请告诉我。提前谢谢你的帮助 通过执行以下操作,我无法获得stackoverflow错误:
pageDisplay newPage = new pageDisplay();
db.Configuration.ProxyCreationEnabled = false;
newPage.Pages = AutoMapper.Mapper.Map<List<PagesViewModel>>(db.Pages.ToList()).ToPagedList(page ?? 1, 20);
pageDisplay newPage=new pageDisplay();
db.Configuration.ProxyCreationEnabled=false;
newPage.Pages=AutoMapper.Mapper.Map(db.Pages.ToList()).ToPagedList(第1页,第20页);
我在这里发现:
但正如文章中所述,关闭代理创建将关闭延迟加载,因此我必须单独加载每个相关实体
这是一个黑客解决方案,因此如果有人找到更好的解决方法,请告诉我。我宁愿获取所有相关实体,而不必稍后加载它们。问题是,它使用AutoMapper创建堆栈溢出。虽然我不完全确定代理创建为什么会导致问题,但我知道有两种解决方法不需要您关闭代理创建/延迟加载(至少不是永久性地用于全局范围):
选项A:如果要使用:
private string PagesURL;
[Required]
[Display(Name = "Page URL")]
[DataType(DataType.Url)]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long and no longer than {1} characters.", MinimumLength = 2)]
public string pagesURL
{
get { return PagesURL; }
set { PagesURL = HttpUtility.UrlEncode(value); }
}
// disable proxy creation just for the duration of query
_context.Configuration.ProxyCreationEnabled = false;
// do the query, map, go crazy!
// enable proxy again. or if your context goes out of scope after this call, then you can ignore re-enabling.
_context.Configuration.ProxyCreationEnabled = true;
选项B:如果不使用投影
var entity = _context.Where(...); // or whatever query
// detach entity
_context.Entry(entity).State = EntityState.Detached;
// then call Map
现在阅读您的更新,可能还有第三个选项:
选项C:修复您的模型
- EF不会生成视图模型,因此您应该能够更改它们以删除循环引用
Ignore
应该可以工作。我要说的是,再仔细看看你为什么或者在哪里会犯这样的错误。我以前没有见过它,我以前也映射过类似的属性
如果您可以发布完整的模型、视图模型和数据库调用相关代码,这会有所帮助。可能是一个模型,查看模型以保持简洁。我刚刚在Automapper中尝试了MaxDepth()
方法,并得到了Automapper给出的解决“StackOverflowException”异常
CreateMap<Pages, PagesViewModel>().MaxDepth(5);
CreateMap().MaxDepth(5);
只需尝试上面的代码,并暂时避免异常。CreateMap().preserverences();
CreateMap<AppUser, AppUserDTO>().PreserveReferences();
这个也对我有用 您的属性需要一个支持字段(publicstringpagesurl
),感谢您链接该字段。我看上去很努力,找不到这样的解决办法。非常感谢。非常感谢。谢谢大家!@Habib我已将属性更改为具有支持字段(所有字段),但它仍然向我抛出错误。您介意删除复制吗?如果您使用的是投影,关闭代理创建是唯一的方法。如果不使用投影,则拆离图元