Получение двойных данных в БД - PullRequest
0 голосов
/ 29 мая 2018

Я получаю данные студента из 2 баз данных.1 из онлайнового API SOAP, который может обрабатывать асинхронные вызовы, и 1 из локальной БД со старыми сервисами, которые не поддерживают асинхронность.
Я сравниваю эти базы данных и записываю различия в локальную sqlDB через EF.

Проблема:
Я получаю двойные записи в моей БД EF.Он помещает правильные данные и количество в массивы внутри метода, но похоже, что когда он нажимает на db.savechanges (), он перепрыгивает на несколько строк вверх и снова сохраняет данные.
Я даже не знаю, где этот дополнительный потокпроисходит от.

Возможно, какой-то код все еще существует в результате многочисленных попыток его решить.Например, я пытался с addrange, но я получаю сообщение об ошибке, когда он пытается добавить FullVarianceList.

public async Task<bool> FullStudentCompare(string date) //format DD/MM/YYYY
{
    try
    {
        //DB context
        using (var db = new SchoolDbContext())
        {
            //GET DATA
            //SMT (async)
            List<SmtStudent> smtStdudentList = await GetAllSmartschoolStudents();
            //Wisa (sync)
            //on date, or if emty on current systemdate
            List<WisaStudent> wisaList;
            if (date == "")
            {
                wisaList = GetWisaStudentData(DateTime.Now.ToShortDateString());
            }
            else
            {
                wisaList = GetWisaStudentData(date);
            }


            //Flags and props needed for DB entry after compare
            bool existsInLocalDb = false;
            List<Variance> vList = new List<Variance>();
            //Full list to add to DB outside foreach
            List<Variance> fullVarianceList = new List<Variance>();
            //Full List of new Students to write to DB outside foreach
            List<DbStudent> fullStudentList = new List<DbStudent>();

            //Compare lists
            foreach (WisaStudent wstd in wisaList)
            {
                //determine correct classCode
                string klasCode;
                if (wstd.klasgroep.Trim() == "Klasgroep 00")
                {
                    klasCode = wstd.klas.Trim();
                }
                else
                {
                    klasCode = wstd.klasgroep.Trim();
                }


                //Create SmtStudent object for compare
                SmtStudent tempStd = new SmtStudent(true,
                                                    wstd.voornaam.Trim(),
                                                    wstd.naam.Trim(),
                                                    wstd.stamboeknummer.Trim(),
                                                    wstd.geslacht.Trim(),
                                                    wstd.geboortedatum.Trim(),
                                                    wstd.straat.Trim(),
                                                    wstd.huisnummer.Trim(),
                                                    wstd.busnummer.Trim(),
                                                    wstd.postcode.Trim(),
                                                    wstd.gemeente.Trim(),
                                                    wstd.emailadres.Trim(),
                                                    wstd.GSM_nummer.Trim(),
                                                    wstd.levensbeschouwing.Trim(),
                                                    wstd.coaccountmoedervoornaam.Trim(),
                                                    wstd.coaccountmoedernaam.Trim(),
                                                    wstd.coaccountmoederemailadres.Trim(),
                                                    wstd.coaccountmoederGSM_nummer.Trim(),
                                                    wstd.coaccountvadervoornaam.Trim(),
                                                    wstd.coaccountvadernaam.Trim(),
                                                    wstd.coaccountvaderemailadres.Trim(),
                                                    wstd.coaccountvaderGSM_nummer.Trim(),
                                                    klasCode,
                                                    wstd.nationaliteit,
                                                    wstd.geboorteGemeente,
                                                    wstd.geboorteLand
                                                    );


                //Find matching SmtStudent
                SmtStudent smtStd = smtStdudentList.Find(i => i.Internnummer == wstd.stamboeknummer);


                //Find matching Std in local DB
                DbStudent dbStd = await db.Students.Where(i => i.Stamboeknummer == wstd.stamboeknummer).FirstOrDefaultAsync();

                //if none exists in the local DB create an entity to update and write to DB
                if (dbStd == null)
                {
                    dbStd = new DbStudent(wstd.voornaam.Trim(),
                                             wstd.naam.Trim(),
                                             wstd.stamboeknummer.Trim(),
                                             wstd.geslacht.Trim(),
                                             wstd.geboortedatum.Trim(),
                                             wstd.straat.Trim(),
                                             wstd.huisnummer.Trim(),
                                             wstd.busnummer.Trim(),
                                             wstd.postcode.Trim(),
                                             wstd.gemeente.Trim(),
                                             wstd.emailadres.Trim(),
                                             wstd.GSM_nummer.Trim(),
                                             wstd.levensbeschouwing.Trim(),
                                             wstd.coaccountmoedervoornaam.Trim(),
                                             wstd.coaccountmoedernaam.Trim(),
                                             wstd.coaccountmoederemailadres.Trim(),
                                             wstd.coaccountmoederGSM_nummer.Trim(),
                                             wstd.coaccountvadervoornaam.Trim(),
                                             wstd.coaccountvadernaam.Trim(),
                                             wstd.coaccountvaderemailadres.Trim(),
                                             wstd.coaccountvaderGSM_nummer.Trim(),
                                             klasCode,
                                             wstd.loopbaanDatum,
                                             wstd.nationaliteit,
                                             wstd.geboorteGemeente,
                                             wstd.geboorteLand
                                             );

                    db.Students.Add(dbStd);
                    fullStudentList.Add(dbStd);
                }
                else
                {
                    existsInLocalDb = true;
                }

                if (smtStd == null)
                {
                    //Std doesn't exist in Smt -> New student
                    dbStd.IsNewStudent = true;
                    dbStd.ClassMovement = true;

                    //remove from wisaList
                    wisaList.Remove(wstd);
                }
                else
                {
                    //clear vlist from previous iterations
                    vList.Clear();

                    //get all properties on the obj, cycle through them and find differences
                    PropertyInfo[] props = smtStd.GetType().GetProperties();

                    vList.AddRange(props.Select(f => new Variance
                    {
                        Property = f.Name,
                        ValueA = f.GetValue(smtStd),
                        ValueB = f.GetValue(tempStd),
                        Checked = false
                    })
                       .Where(v => !v.ValueA.Equals(v.ValueB) && v.ValueB != null)
                       .ToList());


                    //If the users allrdy exists in LocalDb delete all previously recorded variances
                    if (existsInLocalDb)
                    {
                        if (db.Variances.Where(j => j.Student.StudentId.Equals(dbStd.StudentId)).FirstOrDefault() != null)
                        {                            //if the student allready exists we will recreate the variancelist, hence deleting all current items first
                            List<Variance> existingList = db.Variances.Where(j => j.Student.StudentId.Equals(dbStd.StudentId)).ToList();
                            foreach (Variance v in existingList)
                            {
                                db.Variances.Remove(v);
                            }
                        }
                    }

                    //Add new variances if vList is not empty
                    if (vList.Count > 0)
                    {
                        //Check if KlasCode is a variance -> set classmovement to true
                        if (vList.Where(i => i.Property == "KlasCode").FirstOrDefault() != null)
                        {
                            dbStd.ClassMovement = true;
                        }
                        else
                        {
                            dbStd.ClassMovement = false;
                        }

                        //add the StudentObject to the variance to link them 1-many
                        foreach (Variance v in vList)
                        {
                            v.Student = dbStd;
                            fullVarianceList.Add(v);
                            db.Variances.Add(v);
                        }
                    }
                }
            }

            //add the full lists of variances and new students to DB
            //db.Variances.AddRange(fullVarianceList);
            //db.Students.AddRange(fullStudentList);

            db.SaveChanges();

            return true;
        }
    }
    catch(Exception ex)
    {
        return false;
    }
}

1 Ответ

0 голосов
/ 29 мая 2018

Пара вещей:

  1. Важно понимать, что EF использует шаблон единицы работы, где ни одно из изменений в объектах не сохраняется до тех пор, пока не будет вызван SaveChanges, который объясняет«как только он попадает в базу данных db.Savechanges (), он подпрыгивает».

  2. Если у вас есть отношение 1 ко многим, и вы назначаете коллекцию сущностей свойству навигации в другой сущности, а затем добавляете эту родительскую сущность в DbContext, EF помечает эти дочерние сущности какбыть добавленным тоже.В вашем случае dbStd добавляется в строку "db.Students.Add (dbStd);"и в строке "v.Student = dbStd;".Это наиболее вероятно, что вызывает ваши дубликаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...