我遇到了一个奇怪的问题,当使用嵌套的上下文实例多次调用SaveChanges()
时(即使用using来创建上下文的实例),它会插入重复的内容,而不是更新它。
基本上,我正在嵌套两个上下文,将两行插入两个不同的表(使用两个不同的上下文),然后更新其中一行。
即。
插入表A 插入表B 使用表B中的值更新表A
在我更新表A时,它会根据需要成功更新行,但它也会插入一个重复的行(没有更新的值)。
有人能说清楚为什么会发生这种情况吗?
干杯
加文
编辑:道歉,我知道我应该发布一些代码来帮助,但我认为这可能会让人感到困惑。
public ActionResult Payment(int packageID, string action)
{
int c = 0;
using (PackageContext pc = new PackageContext())
{
Package selectedPackage = pc.Packages.Find(packageID);
// store the user's package
UserSubscriptionHistory sub;
using (UserSubscriptionHistoryContext ushc = new UserSubscriptionHistoryContext())
{
sub = new UserSubscriptionHistory();
sub.UserID = Core.CurrentUserID;
sub.PackageID = packageID;
sub.Duration = selectedPackage.Duration;
sub.Cost = selectedPackage.Cost;
ushc.History.Add(sub);
c = ushc.SaveChanges(); // c returns 1 row changed, as one row is inserted
if (c == 0)
{
throw new Exception("An unknown error occured");
}
// has the user selected a trial package?
if (!selectedPackage.IsTrial.HasValue || !selectedPackage.IsTrial.Value)
{
// get me some money ;)
Paypal pp = new Paypal();
PaymentTransaction tran;
using (PaymentTransactionContext ptc = new PaymentTransactionContext())
{
tran = new PaymentTransaction();
tran.UserSubscriptionHistoryID = sub.UserSubscriptionHistoryID;
tran.UserID = Core.CurrentUserID;
tran.Description = "hidden";
tran.Amount = selectedPackage.Cost;
ptc.Transactions.Add(tran);
c = ptc.SaveChanges(); // c returns 1 row changed, as one row is inserted
if (c == 0)
{
throw new Exception("An unknown error occured");
}
sub.TransactionID = tran.PaymentTransactionID;
c = ushc.SaveChanges(); // c returns 2, as one row is updated, but the duplicate is inserted.
if (c == 0)
{
throw new Exception("An unknown error occured");
}
string success = Core.ResolveServerUrl(Url.Action("validate_payment", "User", new { accountAction = action }));
string cancelled = Core.ResolveServerUrl(Url.Action("cancelled", "User"));
string notification = Core.ResolveServerUrl(Url.Action("Process", "Payment"));
string token = pp.SetExpressCheckout(selectedPackage.Cost.ToString("#.##"), tran.Description, tran.PaymentTransactionID.ToString(), success, cancelled, notification, com.paypal.soap.api.PaymentActionCodeType.Sale, com.paypal.soap.api.CurrencyCodeType.GBP);
if (token != "Failure")
{
tran.VendorToken = token;
ptc.SaveChanges();
return Redirect(string.Format("https://www.{0}paypal.com/webscr?cmd=_express-checkout&token={1}", (PaypalConfiguration.Sandbox ? "sandbox." : ""), token));
}
else
{
ViewBag.Error = "Unable to take your payment, please contact us";
}
}
}
}
}
Core.CurrentUser = null;
return RedirectToActionPermanent("account", new { random = DateTime.Now.Ticks });
}
请在每次SaveChanges()
来电后查看评论。
编辑2:我已经设法通过执行以下操作来解决此问题,尽管它看起来不像以前那样整洁:
public ActionResult Payment(int packageID, string action)
{
int c = 0;
using (PackageContext pc = new PackageContext())
{
Package selectedPackage = pc.Packages.Find(packageID);
// store the user's package
UserSubscriptionHistory sub;
using (UserSubscriptionHistoryContext ushc = new UserSubscriptionHistoryContext())
{
sub = new UserSubscriptionHistory();
sub.UserID = Core.CurrentUserID;
sub.PackageID = packageID;
sub.Duration = selectedPackage.Duration;
sub.Cost = selectedPackage.Cost;
ushc.History.Add(sub);
c = ushc.SaveChanges();
}
if (c == 0)
{
throw new Exception("An unknown error occured");
}
// has the user selected a trial package?
if (!selectedPackage.IsTrial.HasValue || !selectedPackage.IsTrial.Value)
{
// get me some money ;)
Paypal pp = new Paypal();
PaymentTransaction tran;
using (PaymentTransactionContext ptc = new PaymentTransactionContext())
{
tran = new PaymentTransaction();
tran.UserSubscriptionHistoryID = sub.UserSubscriptionHistoryID;
tran.UserID = Core.CurrentUserID;
tran.Description = "hidden";
tran.Amount = selectedPackage.Cost;
ptc.Transactions.Add(tran);
c = ptc.SaveChanges();
}
if (c == 0)
{
throw new Exception("An unknown error occured");
}
using (UserSubscriptionHistoryContext ushc = new UserSubscriptionHistoryContext())
{
ushc.History.Attach(sub);
sub.TransactionID = tran.PaymentTransactionID;
c = ushc.SaveChanges();
}
if (c == 0)
{
throw new Exception("An unknown error occured");
}
string success = Core.ResolveServerUrl(Url.Action("validate_payment", "User", new { accountAction = action }));
string cancelled = Core.ResolveServerUrl(Url.Action("cancelled", "User"));
string notification = Core.ResolveServerUrl(Url.Action("Process", "Payment"));
string token = pp.SetExpressCheckout(selectedPackage.Cost.ToString("#.##"), tran.Description, tran.PaymentTransactionID.ToString(), success, cancelled, notification, com.paypal.soap.api.PaymentActionCodeType.Sale, com.paypal.soap.api.CurrencyCodeType.GBP);
if (token != "Failure")
{
using (PaymentTransactionContext ptc = new PaymentTransactionContext())
{
ptc.Transactions.Attach(tran);
tran.VendorToken = token;
ptc.SaveChanges();
}
return Redirect(string.Format("https://www.{0}paypal.com/webscr?cmd=_express-checkout&token={1}", (PaypalConfiguration.Sandbox ? "sandbox." : ""), token));
}
else
{
ViewBag.Error = "Unable to take your payment, please contact us";
}
}
}
Core.CurrentUser = null;
return RedirectToActionPermanent("account", new { random = DateTime.Now.Ticks });
}