Exemplo n.º 1
0
        /// <summary>
        /// Reads the middle table of many-to-many relationship. Bad performance currently, because it reads the
        /// middle file everytime a record is read.
        /// </summary>
        /// <param name="rec"></param>
        public void ReadMTM(BaseClass rec)
        {
            foreach (MTMRelationInfo mtmInfo in rec.MTMInfoList())
            {
                String        filepath  = Path.Combine(ctx.DatabaseFolder, mtmInfo.tableName) + ".dat"; //mtm middle tablo yolu
                Stream        mtmStream = File.OpenRead(filepath);
                int           line      = Convert.ToInt32(mtmStream.Length / (sizeof(int) * 3));
                List <MTMRec> mtmRecs   = new List <MTMRec>(); //middle tablo kayıtları
                for (int i = 0; i < line; i++)
                {
                    Tuple <DKDB.BaseClass, Dictionary <PropertyInfo, int> > fillingLog;

                    fillingLog = FileOps.ReadSingleRecord(mtmStream, i + 1, typeof(MTMRec));
                    mtmRecs.Add((MTMRec)fillingLog.Item1);
                }
                mtmStream.Close();
                int    my_id_column = WhoAmI(mtmInfo.tableName); //MTMRec içinde id1 mi benim sütunum yoksa id2 mi? ctx'teki sıraya göre kontrol edilir
                MTMReq mtmReq       = new MTMReq(rec, mtmInfo.OwnMTMProp);

                foreach (MTMRec mtmRec in mtmRecs) //her bir middle tablo kaydı için:
                {
                    if (my_id_column == 1 && mtmRec.id_1 == rec.id)
                    {
                        mtmReq.AddOppId(mtmRec.id_2);//opposite id
                    }
                    else if (my_id_column == 2 && mtmRec.id_2 == rec.id)
                    {
                        mtmReq.AddOppId(mtmRec.id_1);//opposite id
                    }
                }

                KeyValuePair <string, Tuple <Type, Type> > kp = BaseClass.AllMTMRelations.FirstOrDefault(r => r.Key == mtmInfo.tableName);
                object   opposite_dbset = ctx.GetDBSetByType(my_id_column == 1 ? kp.Value.Item2 : kp.Value.Item1);
                object[] parameters     = new object[1];

                parameters[0] = mtmReq; //list of ids of the records that we want to read from opposite db
                PropertyInfo  fi      = opposite_dbset.GetType().GetProperty("MTMReqList");
                List <MTMReq> rtbfMTM = fi.GetValue(opposite_dbset) as List <MTMReq>;
                rtbfMTM.GetType().GetMethod("Add").Invoke(rtbfMTM, parameters);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Completes changes in the dbset chosen by the command.
        /// </summary>
        /// <param name="command">AddDirectly, AddChilds, Update, Remove</param>
        public bool SaveChanges(char[] com)
        {
            String command = new string(com);
            bool   result  = false;

            if (command == "AddOTM")
            {
                while (recordsToAddAsOTM.Count() != 0)
                {
                    Tuple <object, object, PropertyInfo> rec = recordsToAddAsOTM[0];
                    OpenMainWrite();
                    rec.Item3.SetValue(rec.Item2, rec.Item1);
                    int fk = FileOps.Add(mainFile, removedIndexes, (BaseClass)rec.Item2);
                    rec.Item2.GetType().GetProperty(rec.Item3.Name).SetValue(rec.Item2, fk);
                    result = true;
                }
            }
            else if (command == "AddDirectly")
            {
                //0. elemanlar ile işlem yapma nedeni:
                //Bir ekleme işlemi yapılırken, içinde çocuk nesne var ise, bir şekilde üzerinde çalışılan
                //listenin sonuna yeni kayıt eklenmesine neden olabilir.
                OpenMainWrite();
                while (recordsToAddDirectly.Count() != 0)
                {
                    result = true;
                    int id = FileOps.Add(mainFile, removedIndexes, recordsToAddDirectly[0]);
                    recordsToAddDirectly[0].id = id;
                    allRecords.Add(recordsToAddDirectly[0]);
                    recordsToAddDirectly.RemoveAt(0);
                }
                mainFile.Close();
            }
            else if (command == "AddChilds")
            {
                OpenMainWrite();
                while (recordsToAddAsOTO.Count() != 0)
                {
                    result = true;
                    //item1=parent, item2=child
                    T   record = (T)recordsToAddAsOTO[0].Item2;
                    int fk     = FileOps.Add(mainFile, removedIndexes, record);
                    record.id = fk;
                    Type     ownerType      = recordsToAddAsOTO[0].Item1.GetType();
                    Type     ownerDbSetType = ctx.dbsetTypes.Where(a => a.ToString().Equals(ownerType.ToString())).ElementAt(0);
                    object   ownerDbSet     = ctx.GetDBSetByType(ownerDbSetType);
                    object[] parameters     = new object[1];
                    parameters[0] = (BaseClass)recordsToAddAsOTO[0].Item1;
                    //Explained under recordsToAddAsOTO declaration.
                    ownerDbSet.GetType().GetMethod("Update").Invoke(ownerDbSet, parameters);
                    allRecords.Add(record);
                    recordsToAddAsOTO.RemoveAt(0);
                }
                mainFile.Close();
            }
            else if (command == "Update")
            {
                OpenMainWrite();
                while (Updates.Count() != 0)
                {
                    result = true;
                    T record = Updates[0];
                    FileOps.Overwrite(mainFile, record);
                    Updates.RemoveAt(0);
                }
                mainFile.Close();
            }
            else if (command == "Remove")
            {
                OpenMainWrite();
                while (recordsToRemove.Count() != 0)
                {
                    result = true;
                    recordsToRemove[0].GetType().GetProperty("removed").SetValue(recordsToRemove[0], true);
                    FileOps.Remove(mainFile, metaFile, recordsToRemove[0]);
                    if (!ctx.removed.Any(kp => kp.Key == typeof(T)))
                    {
                        ctx.removed.Add(typeof(T), new List <int>());
                    }
                    ctx.removed.FirstOrDefault(kp => kp.Key == typeof(T)).Value
                    .Add((int)recordsToRemove[0].id);
                    recordsToRemove.RemoveAt(0);
                }
                mainFile.Close();
            }
            else if (command == "UpdateAfterRemoval") //silinmiş bir kayda referans olanların foreign keylerini -1 yapacak
            {
                List <PropertyInfo>           toChangeColumns = new List <PropertyInfo>();
                Dictionary <int, List <int> > toChange        = new Dictionary <int, List <int> >();
                foreach (KeyValuePair <Type, List <int> > kp in ctx.removed)
                {
                    List <PropertyInfo> props = this.GetType().GetGenericArguments()[0].GetProperties().ToList();
                    foreach (PropertyInfo info in props)
                    {
                        if (!info.PropertyType.IsGenericType && info.PropertyType.Name.Equals(kp.Key.Name))
                        {
                            toChangeColumns.Add(info);
                            foreach (int id in kp.Value) //null yapılacak id
                            {
                                toChange.Add(id, new List <int>());
                            }
                        }
                        else if (info.PropertyType.IsGenericType && info.PropertyType.GetGenericArguments()[0].Name == kp.Key.Name)
                        {
                            //remove from mtm
                        }
                    }
                }
                foreach (T rec in allRecords)
                {
                    foreach (PropertyInfo column in toChangeColumns)
                    {
                        foreach (KeyValuePair <int, List <int> > kp in toChange)
                        {
                            BaseClass child_rec = (BaseClass)rec.GetType().GetProperty(column.Name).GetValue(rec);
                            if (child_rec.id == kp.Key)
                            {
                                rec.GetType().GetProperty(column.Name).SetValue(rec, null);
                                kp.Value.Add(rec.id);
                            }
                        }
                    }
                }
                foreach (PropertyInfo column in toChangeColumns)
                {
                    OpenMainWrite();
                    FileOps.MakeReferenceNull(mainFile, column, typeof(T), toChange);
                    mainFile.Close();
                }
            }

            return(result);
        }