SaveChanges вставляет дублированный контент - PullRequest
0 голосов
/ 26 марта 2012

Я столкнулся со странной проблемой, когда при многократном вызове SaveChanges() с использованием вложенных экземпляров контекста (т. Е. С помощью использования для создания экземпляра контекста) он вставляет дублирующее содержимое вместо его обновления.

По сути, я вложил два контекста, вставил две строки в две разные таблицы (используя два разных контекста) и затем обновил одну из этих строк.

т.е.

Вставить в таблицу А Вставить в таблицу B Обновить таблицу A значением из таблицы B

В тот момент, когда я иду к обновлению таблицы A, она успешно обновляет строку по мере необходимости, но также вставляет дублирующую строку (без обновленных значений).

Может ли кто-нибудь пролить свет на то, почему это может произойти?

Приветствия

Gavin

Редактировать: Извините, я знал, что должен был опубликовать некоторый код, чтобы помочь, но я думал, что это может смутить людей.

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 });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...