C# 调用.SubmitChanges()linq时获得随机堆栈溢出
调用C# 调用.SubmitChanges()linq时获得随机堆栈溢出,c#,linq,stack-overflow,C#,Linq,Stack Overflow,调用{DataContext}.SubmitChanges()时,我遇到堆栈溢出异常。。。我希望我知道要发布哪些代码行来帮助澄清情况,但异常在抛出时没有提供任何信息,它说: An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll 然后在查看详细信息时,我得到: {Cannot evaluate expression because the current thread is
{DataContext}.SubmitChanges()
时,我遇到堆栈溢出异常。。。我希望我知道要发布哪些代码行来帮助澄清情况,但异常在抛出时没有提供任何信息,它说:
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
然后在查看详细信息时,我得到:
{Cannot evaluate expression because the current thread is in a stack overflow state.}
我查看了此视图模型中的所有属性,以确保所有内容都正确声明,并且没有导致stackoverflow异常的问题……只有在调用SubmitChanges()
后才会发生此异常
下面是调用submit的代码:
public void VerifyAdvancePaymentsAndSave()
{
try
{
if (!VerifyTakeHomeActualBreakDownForAdvancePayments())
{
MessageBox.Show(
"Cash, Check, and Money Order fields must add up to the amount in the Take Home Actual field!",
"Validation Error!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
if (MessageBox.Show("Are you sure you want to save this payment?", "Save", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
return;
if (!UserController.CreateUserController().CheckAccess(UserController.RestrictedAccessAction.EditCollections))
{
return;
}
if (InitialCollectionAction == CollectionAction.ViewAdvancePayment)
{
foreach (Advance a in Advances)
{
foreach (AdvancePayment ap in a.AdvancePayments)
{
AdvancePayment newAP = sp.AdvancePayments.Where(adv => adv.Id == ap.Id).SingleOrDefault();
if (newAP != null)
{
newAP.Payment = ap.Payment;
newAP.IsSaved = false;
}
else
{
MessageBox.Show("Could not find Advance Payment to apply amount to!");
return;
}
}
}
}
else
{
try
{
CurrentCollection.Status = BatchStatus.Open.ToString();
CurrentCollection.CollectionDate = DateTime.Now;
CurrentCollection.IsAdvancedPayment = true;
CurrentCollection.CollectionMachines = null;
//sp.Collections.InsertOnSubmit(CurrentCollection);
}
catch
{
MessageBox.Show("Error inserting changes!");
}
}
try
{
sp.SubmitChanges();
if (InitialCollectionAction == CollectionAction.ViewAdvancePayment)
MessageBox.Show("Advance Payment was saved Successfully!");
else
MessageBox.Show("Advance Payment was submitted Sucessfully!");
CloseTab();
}
catch
{
MessageBox.Show("Error submitting changes!");
}
}
catch (Exception ex)
{
string message = UserController.CreateUserController().LoggedInUser.UserName + "\n" + ex.Message + "\n" + ex.StackTrace;
EmailController.CreateEmailController().SendEmail("URM Error", message);
}
}
堆栈跟踪-在SubmitChanges()调用之前
此视图模型中使用的模型:
public class AdvancePaymentsModel : INotifyPropertyChanged
{
public int AdvanceId { get; set; }
public string PaymentId { get; set; }
public decimal Payment { get; set; }
public DateTime PaymentDate { get; set; }
private string _status;
public string Status
{
get
{
return _status;
}
set
{
_status = value;
OnPropertyChanged("Status");
}
}
private Brush _brushObj;
public Brush BrushObj
{
get
{
return _brushObj;
}
set
{
_brushObj = value;
OnPropertyChanged("BrushObj");
}
}
private AdvancePayment _advancePayment;
public AdvancePayment AdvancePayment
{
get
{
return _advancePayment;
}
set
{
_advancePayment = value;
OnPropertyChanged("AdvancePayment");
}
}
private Visibility _voidButtonVisibility;
public Visibility VoidButtonVisibility
{
get
{
return _voidButtonVisibility;
}
set
{
_voidButtonVisibility = value;
OnPropertyChanged("VoidButtonVisibility");
}
}
}
public class AdvancePaymentsModel : INotifyPropertyChanged
{
public int AdvanceId { get; set; }
public string PaymentId { get; set; }
public decimal Payment { get; set; }
public DateTime PaymentDate { get; set; }
private string _status;
public string Status
{
get
{
return _status;
}
set
{
_status = value;
OnPropertyChanged("Status");
}
}
private Brush _brushObj;
public Brush BrushObj
{
get
{
return _brushObj;
}
set
{
_brushObj = value;
OnPropertyChanged("BrushObj");
}
}
private AdvancePayment _advancePayment;
public AdvancePayment AdvancePayment
{
get
{
return _advancePayment;
}
set
{
_advancePayment = value;
OnPropertyChanged("AdvancePayment");
}
}
private Visibility _voidButtonVisibility;
public Visibility VoidButtonVisibility
{
get
{
return _voidButtonVisibility;
}
set
{
_voidButtonVisibility = value;
OnPropertyChanged("VoidButtonVisibility");
}
}
}
}
启用调试.Net Framework源代码后。。。我看到在dispatcher类中抛出stackoverflow异常
private void PushFrameImpl(DispatcherFrame frame)
{
SynchronizationContext oldSyncContext = null;
SynchronizationContext newSyncContext = null;
MSG msg = new MSG();
_frameDepth++;
try
{
// Change the CLR SynchronizationContext to be compatable with our Dispatcher.
oldSyncContext = SynchronizationContext.Current;
newSyncContext = new DispatcherSynchronizationContext(this);
SynchronizationContext.SetSynchronizationContext(newSyncContext);
try
{
while(frame.Continue)
{
if (!GetMessage(ref msg, IntPtr.Zero, 0, 0))
break;
TranslateAndDispatchMessage(ref msg); //*<--------- gets thrown here*
}
// If this was the last frame to exit after a quit, we
// can now dispose the dispatcher.
if(_frameDepth == 1)
{
if(_hasShutdownStarted)
{
ShutdownImpl();
}
}
}
finally
{
// Restore the old SynchronizationContext.
SynchronizationContext.SetSynchronizationContext(oldSyncContext);
}
}
finally
{
_frameDepth--;
if(_frameDepth == 0)
{
// We have exited all frames.
_exitAllFrames = false;
}
}
}
所以在接受了@KellyGendron和@David的建议后,我最终得到了在ChangeTracker类中抛出的stackoverflow异常
internal override bool IsMemberPendingGeneration(MetaDataMember keyMember) {
if (this.IsNew && keyMember.IsDbGenerated) {
return true;
}
// look for any FK association that has this key member (should only be one)
foreach (MetaAssociation assoc in type.Associations) {
if (assoc.IsForeignKey) {
/*CRASHES HERE*/ int index = assoc.ThisKey.IndexOf(keyMember);
if (index > -1) {
// we must have a reference to this other object to know if its side of
// the association is generated or not
object otherItem = null;
if (assoc.ThisMember.IsDeferred) {
otherItem = assoc.ThisMember.DeferredValueAccessor.GetBoxedValue(this.current);
}
else {
otherItem = assoc.ThisMember.StorageAccessor.GetBoxedValue(this.current);
}
if (otherItem != null) {
if (assoc.IsMany) {
// Can't be pending generation for a value that would have to be the same
// across many rows.
continue;
}
else {
StandardTrackedObject trackedOther = (StandardTrackedObject)this.tracker.GetTrackedObject(otherItem);
if (trackedOther != null) {
MetaDataMember otherMember = assoc.OtherKey[index];
return trackedOther.IsMemberPendingGeneration(otherMember);
}
}
}
}
}
}
return false;
}
}
}
keymember似乎来自于Location类(数据库表)的部分可用属性,它似乎被卡在ID列上,我可能读错了代码,然而,在这段代码中,它看起来像是newAP.Payment指向了它自己,这可能是让序列化程序如此困惑的原因。如果我误读了,请再次原谅我,今天睡眠非常缺乏
foreach (AdvancePayment ap in a.AdvancePayments)
{
AdvancePayment newAP = sp.AdvancePayments
.Where(adv => adv.Id == ap.Id).SingleOrDefault();
if (newAP != null)
{
newAP.Payment = ap.Payment;
...
如果不是这样,您可能希望尝试将保存拆分为多个部分,例如将关联设置为null,然后按ID指定。这里有一个类似的情况可能会有所帮助。。。
在做了很多事情之后,我的一个表的主键有一个外键,这就成了一个问题。这导致出现循环引用。我发现最好的调试方法是启用.NET源代码的调试,然后我必须在ViewModel中的OnPropertyChanged方法中放置一个断点。在这一点上,我能够使异常发生在ChangeaTracker类中,否则它将在Dispatcher类中中断…请显示一些代码以便我们提供帮助。获取堆栈跟踪以观察循环。只是猜测(因此使用注释而不是回答)但是您是否有一个递归数据结构,在序列化过程中没有检测到它?要调试SubmitChanges()调用,您应该打开工具->选项->调试->启用.NET Framework(另请参见:)@usr A stackoverflow无法显示stacktrace。此代码不会被调用…它会进入else语句中,这是crashingAre您确定在上一次迭代中它没有被指向自身吗?您可能还想尝试在方法中的每个db更改之后添加sp.SubmitChanges()。别把它们留在那里很明显,但可能会帮助您准确地看到查询的哪一部分使其阻塞。我不认为我在此处放置了断点,并且此代码从未被调用…也许我应该将代码发布在预付款获得savedahhh的位置…我不知道如何,但不知怎的,数据库中的位置表最终将外键添加到其自己的主键…这这似乎是一个非常愚蠢的发现……是否允许将您的答案标记为正确答案?因为这(以及大卫的帮助)让我找到了问题?@jharr100:我建议您添加一个自己的新答案,在其中解释问题并将其标记为“社区维基”。然后:接受你自己的答案并投票表决。这样人们就不会在遇到同样的问题时感到困惑。太好了!当这些问题找不到答案的时候,我总是很难受。
internal override bool IsMemberPendingGeneration(MetaDataMember keyMember) {
if (this.IsNew && keyMember.IsDbGenerated) {
return true;
}
// look for any FK association that has this key member (should only be one)
foreach (MetaAssociation assoc in type.Associations) {
if (assoc.IsForeignKey) {
/*CRASHES HERE*/ int index = assoc.ThisKey.IndexOf(keyMember);
if (index > -1) {
// we must have a reference to this other object to know if its side of
// the association is generated or not
object otherItem = null;
if (assoc.ThisMember.IsDeferred) {
otherItem = assoc.ThisMember.DeferredValueAccessor.GetBoxedValue(this.current);
}
else {
otherItem = assoc.ThisMember.StorageAccessor.GetBoxedValue(this.current);
}
if (otherItem != null) {
if (assoc.IsMany) {
// Can't be pending generation for a value that would have to be the same
// across many rows.
continue;
}
else {
StandardTrackedObject trackedOther = (StandardTrackedObject)this.tracker.GetTrackedObject(otherItem);
if (trackedOther != null) {
MetaDataMember otherMember = assoc.OtherKey[index];
return trackedOther.IsMemberPendingGeneration(otherMember);
}
}
}
}
}
}
return false;
}
}
}
foreach (AdvancePayment ap in a.AdvancePayments)
{
AdvancePayment newAP = sp.AdvancePayments
.Where(adv => adv.Id == ap.Id).SingleOrDefault();
if (newAP != null)
{
newAP.Payment = ap.Payment;
...