LINQ to SQL submitchanges ничего не делает - PullRequest
2 голосов
/ 22 июня 2011

Моя проблема заключается в следующем: я пытаюсь создать функцию, в которую я мог бы передать список элементов, который затем пошел бы в БД с каждым из этих элементов и обновил бы их.Я полагаю, что проблема в способе использования datacontexts, но я не могу понять эту проблему.

Вот моя функция, которая составляет список элементов, которые были изменены:

 protected void btnSave_Click(object sender, EventArgs e)
{
    List<AFF_CMS_FMA> fmasToSave = new List<AFF_CMS_FMA>();
    AFF_CMS_FMA newFmaItem = new AFF_CMS_FMA();

    foreach (AFF_CMS_FMA fmaItem in FmaLib.fetchAllActiveAssetsInFMA())
    {
        if (fmaItem.SortOrder != Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_SortOrder"]))
        {
            newFmaItem = fmaItem;
            newFmaItem.Name = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_Name"]);
            newFmaItem.AssetID = Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_AssetID"]);
            newFmaItem.SortOrder = Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_SortOrder"]);
            newFmaItem.ImagePathEn = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ImagePathEn"]);
            newFmaItem.ImagePathCh = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ImagePathCh"]);
            newFmaItem.StartDate = DateTime.Parse(SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_StartDate"]));
            newFmaItem.EndDate = DateTime.Parse(SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_EndDate"]));
            newFmaItem.ClickToUrl = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ClickToUrl"]);
            fmasToSave.Add(newFmaItem);

        }
    }
    FmaLib.saveEditedFmas(fmasToSave);
}

вот функция, которую цикл foreach вызывает для получения всех элементов, находящихся в БД:

 public static List<AFF_CMS_FMA> fetchAllActiveAssetsInFMA()
    {
        List<AFF_CMS_FMA> results = null;

        using (fmaDataContext db = new fmaDataContext())
        {
            using (TransactionScope ts = new TransactionScope())
            {
                try
                {
                    if (HttpContext.Current.Cache["fmaActiveList"] == null)
                    {
                        db.LoadOptions = loadAll;
                        results = clsCompiledQuery.getAllActiveFmas(db).ToList();
                        HttpContext.Current.Cache["fmaActiveList"] = results;
                    }
                    else
                        results = (List<AFF_CMS_FMA>)HttpContext.Current.Cache["fmaActiveList"];

                    ts.Complete();
                }
                catch (Exception ex)
                { Transaction.Current.Rollback(); }
            }
            return results;
        }
    }

вот используемые запросы:

 protected static class clsCompiledQuery
    {
        public static Func<DataContext, IOrderedQueryable<AFF_CMS_FMA>>
        getAllActiveFmas = CompiledQuery.Compile((DataContext db)
        => from fma in db.GetTable<AFF_CMS_FMA>()
           where fma.IsArchived == false
           orderby fma.SortOrder ascending
           select fma);


        public static Func<DataContext, int,IQueryable<AFF_CMS_FMA>>
        getFmaById = CompiledQuery.Compile((DataContext db, int ID)
        => from fma in db.GetTable<AFF_CMS_FMA>()
           where fma.ID == ID
           select fma);

    }

и, наконец, я пытался добиться сохранения с БД, но никакие исключения не выбрасываются, но БД этого не делаетизменить

 public static bool saveEditedFmas(List<AFF_CMS_FMA> fmaToSaveList)
    {
        using (fmaDataContext db = new fmaDataContext())
        {
            using (TransactionScope ts = new TransactionScope())
            {
                try
                {
                    foreach (AFF_CMS_FMA fmaItemToSave in fmaToSaveList)
                    {
                        AFF_CMS_FMA fmaItemToUpdate = clsCompiledQuery.getFmaById(db, fmaItemToSave.ID).ToList()[0];
                        fmaItemToUpdate = fmaItemToSave;

                        db.SubmitChanges();
                    }

                    return true;
                }
                catch (Exception ex)
                {
                    Transaction.Current.Rollback();
                    return false;
                }
            }
        }
    }

Я проверил, и таблица содержит первичный ключ в конструкторе.Если я выполняю сохранение из функции btnSave_click путем передачи datacontext в fetchAllActiveAssetsInFMA (), то выполняю submitchanges для этого контекста, это работает ... но я пытаюсь абстрагировать это оттуда.

спасибо всем заранее

1 Ответ

2 голосов
/ 22 июня 2011

Вы не вызываете ts.Complete в функции saveEditedFmas.

Также я бы рекомендовал вызывать db.SubmitChanges(); вне цикла for.А почему у вас транзакция в функции fetchAllActiveAssetsInFMA?Это только выборка данных правильно?И я не совсем уверен, что то, что происходит внутри цикла for в функции сохранения, выглядит странно.

Я думаю, вам следует сопоставить свойства с fmaItemToSave на fmaItemToUpdate

foreach (var fmaItemToSave in fmaToSaveList)
{
   var fmaItemToUpdate = clsCompiledQuery.getFmaById(db, fmaItemToSave.ID).First();
   fmaItemToUpdate.Name    = fmaItemToSave.Name;
   fmaItemToUpdate.AssetID = fmaItemToSave.AssetID;
   //And the rest of the properties           
}
db.SubmitChanges();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...