Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> EF 5 обработка ошибки 
:(
    Опции темы
strS
Дата 2.12.2013, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 19.2.2009

Репутация: нет
Всего: нет



Добрый день!
Есть код добавления новых строк в базу. Периодически при вызове метода SaveChanges() возникает ситуация, когда данные не могут быть сохранены (срабатывает проверка на уникальные поля, ругается что хочу добавить дубли). Вопрос - можно ли как-то обработать это исключение, чтобы после добавления 1000 строк и вызова метода SaveChanges(), при сохранения например 500й строки, вылетела ошибка, а остальные строки сохранились и программа продолжала работать дальше?
Я понимаю что можно сохранять каждую строку по отдельности и обернуть try/catche, только этот способ занимает больше времени.

Код

for (int i = 0; i < NPOBdata.Count; i++)
                {
                    string[] data = NPOBdata[i].GetString(0).Split(new char[] { '|' });

                    NPOB objNPOB = new NPOB
                    {
                        MANDT = data[22],
                        POBNR = long.Parse(data[21]),
                        ORGID = data[20],
                        EINRI = data[19],
                        BAUID = data[18],
                        PERNR = data[17],
                        KALID = data[16],
                        KALMOD = data[15],
                        WPTPOE = data[14],
                        AKTIV = data[13],
                        SRCH_DAYS = int.Parse(data[12]),
                        ERDAT = DateTime.TryParseExact(data[11], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out NullDate) ? DateTime.ParseExact(data[11], "yyyyMMdd", CultureInfo.InvariantCulture) : (DateTime?)null,
                        ERUSR = data[10],
                        UPDAT = DateTime.TryParseExact(data[9], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out NullDate) ? DateTime.ParseExact(data[9], "yyyyMMdd", CultureInfo.InvariantCulture) : (DateTime?)null,
                        UPUSR = data[8],
                        SQ_NR_CAL = int.Parse(data[7]),
                        OVERB = data[6],
                        POBKLCD = data[5],
                        TAVALID = int.Parse(data[4]),
                        TAHOLID = data[3],
                        PERNR_ROOM = data[2],
                        ROOM_PERNR = data[1],
                        TIMESTAMP = decimal.Parse(data[0])
                    };

                    if ((i > 0) && ((double)i % 5000 == 0))
                    {
                        db.SaveChanges();
                        log.Info("  Записано {0} строк из {1}", i, NPOBdata.Count);
                    }
                    db.AddToNPOB(objNPOB);
                }
 
                db.SaveChanges();  //тут если будет дубль в базе, то вылетит ошибка и ничего не сохранится.

                log.Info(" Добавлено строк: {0}", NPOBdata.Count());

PM MAIL   Вверх
AntiInt
Дата 2.12.2013, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 15.5.2009

Репутация: нет
Всего: нет



Если у Вас не отсоединенная модель и вы в пределах контекста, то можно проверить есть ли у же такой ключ в контексте.

PM MAIL   Вверх
strS
Дата 3.12.2013, 06:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 19.2.2009

Репутация: нет
Всего: нет



Цитата(AntiInt @ 2.12.2013,  17:33)
Если у Вас не отсоединенная модель и вы в пределах контекста, то можно проверить есть ли у же такой ключ в контексте.

Данные проверки опять же займут кучу времени
Я тут глянул, выпадает System.Data.SqlClient.SqlException
Может можно его как-то переписать, чтобы он в лог писал о ошибке, а запись не прерывал?

Или я чушь пишу?))))
PM MAIL   Вверх
strS
Дата 3.12.2013, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 19.2.2009

Репутация: нет
Всего: нет



Мне мысля пришла в голову!)
А что если при возникновении ошибки (при сохранении 1000 строк), постараться пробежаться по каждой строке и записывать ее по-отдельности?
Только теперь нужно узнать, где EF хранит список изменений.

Может кто подсказать?
PM MAIL   Вверх
AntiInt
Дата 3.12.2013, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 15.5.2009

Репутация: нет
Всего: нет



вот Вам код, тут по ключу я проверяю есть ли в контексте уже такая запись.
Вам надо этот подход под свои нужны модифицировать.
Код

var localEntry = Set<T>().Local.FirstOrDefault(entity => typeof(T).GetProperty(keyPropertyName).GetValue(entity, null).Equals(typeof(T).GetProperty(keyPropertyName).GetValue(obj, null)));
                if (localEntry == null)
                {
                    Set<T>().Attach(obj);
                    Entry(obj).State = System.Data.EntityState.Modified;
                }
                else
                {
                    Entry(localEntry).CurrentValues.SetValues(obj);
                }

PM MAIL   Вверх
strS
Дата 6.12.2013, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 19.2.2009

Репутация: нет
Всего: нет



AntiInt, спасибо за код, но это не совсем то что мне нужно

Вот я тут немного покопался и сделал так, но у меня постоянно вылетает ошибка с Entry. Поможете?

В базе уже есть запись с полями  MANDT = "900", DOKAR = "B2X". Поля уникальные
Задача в том чтобы при возникновении ошибки обработать набор данных построчно и выявить где именно произошла ошибка, сохранив остальные строки

Код

try
            {
                TDWA a = new TDWA() { MANDT = "900", DOKAR = "B2X" };
                TDWA b = new TDWA() { MANDT = "800", DOKAR = "B2X" };
                TDWA c = new TDWA() { MANDT = "900", DOKAR = "B2X" };
                db.AddToTDWA(a);
                db.AddToTDWA(b);
                db.AddToTDWA(c);
                db.SaveChanges();
            }
            catch (Exception e)
            {
                IEnumerable<System.Data.Objects.ObjectStateEntry> k = db.ObjectStateManager.GetObjectStateEntries(EntityState.Added);
                db = new SAPEntities();
                
                using (SAPEntities db1 = new SAPEntities())
                {
                    foreach (System.Data.Objects.ObjectStateEntry ar in k)
                    {
                        TDWA aa = (TDWA)ar.Entity;
                        db1.AddToTDWA(aa);
                        try
                        {
                             db1.SaveChanges();
                        }
                        catch
                        {
                            log.Error(e.Message);
                        }
                    }
                }
            }

PM MAIL   Вверх
AntiInt
Дата 9.12.2013, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 15.5.2009

Репутация: нет
Всего: нет



Давайте попробуем так это псевдокод(компилятора нет под рукой)
var entities= db1.Entities;//Entities - это метод, который возвращает все Ваши ентити
foreach(var insEntity in EntityForInsertion)
{
    if(!entities.Any(insEntity))
       {
                 db1.Attach(insEntity);
       }
     else
      {
               тут обрабатываем то, что уже существует
      }
}
db1.SaveChanges();
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0761 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.