示例#1
0
        // we always refill the object with the current values from the DB even if we find the object (via PK in our cache)
        // as the expensive operation (fetching from DB is already done) through the cache we just ensure object identity
        private T CreateObject(IDataReader reader)
        {
            // create a new one of T
            var poco    = ObjectFactory.Create(Entity.PocoType);
            var cache   = _ctx.Cache;
            var pkValue = reader[Entity.PkColumn.Name];
            // we now get a new empty cacheEntry or it already was present
            var cacheEntry = cache.GetOrInsert(Entity, (long)pkValue, poco);

            foreach (var col in QueriedColumns)
            {
                if (col.IsDbColumn)
                {
                    if (col.IsShadowAttribute)
                    {
                        // foreign key / ManyToOne (exists in db and in object, but is a key - can not be set directly and needs to be lazily loaded)
                        cacheEntry.ShadowAttributes[col.Name] = reader[col.Name];
                    }
                    else
                    {
                        var value = reader[col.Name];
                        // specially handle enums
                        if (col.PropInfo.PropertyType.IsEnum)
                        {
                            value = Enum.Parse(col.PropInfo.PropertyType, value as string);
                        }
                        // fill the originalEntries with values for changeTracking later
                        if (!cacheEntry.OriginalPoco.ContainsKey(col.Name))
                        {
                            cacheEntry.OriginalPoco.Add(col.Name, value);
                        }
                        // fill the object from the cache with values
                        col.PropInfo.GetSetMethod(true).Invoke(cacheEntry.Poco, new[] { value });
                    }
                }
                else
                {
                    if (col.Relation is ManyToMany relation)
                    {
                    }
                }
            }
            // instantiate the inner lazy loader in the object
            LazyLoadInjector.InjectLazyLoader <T>(poco, _ctx, Entity);
            return((T)cacheEntry.Poco);
        }
示例#2
0
文件: Database.cs 项目: leherv/ORM
        public List <T> ExecuteInsert <T>(InsertStatement <T> statement)
        {
            using var connection = _connection.Invoke();
            connection.Open();
            using IDbTransaction transaction = connection.BeginTransaction();
            using var command   = connection.CreateCommand();
            command.CommandText = statement.AsSqlString();
            command.Transaction = transaction;
            PrepareStatement(statement, command);

            try
            {
                var reader = command.ExecuteReader();

                var entity = statement._entityExecutedOn;
                var pkCol  = entity.PkColumn;
                var pocos  = statement._pocos;
                var cache  = _ctx.Cache;

                var enumerator = pocos.GetEnumerator();
                // now we set the pks the db returned on our pocos and add them to the cache
                while (reader.Read() && enumerator.MoveNext())
                {
                    var poco = enumerator.Current;
                    var pk   = reader[pkCol.Name];
                    pkCol.PropInfo.SetMethod.Invoke(poco, new[] { pk });
                    var cacheEntry = cache.GetOrInsert(entity, (long)pk, poco);

                    // now we fill originalPoco
                    foreach (var col in entity.CombinedColumns())
                    {
                        if (col.IsDbColumn)
                        {
                            if (col.IsShadowAttribute)
                            {
                                // TODO: maybe no entry?
                                cacheEntry.ShadowAttributes[col.Name] = null;
                            }
                            else
                            {
                                var value = col.PropInfo.GetMethod.Invoke(poco, new object[0]);
                                // fill the originalEntries with values for changeTracking later
                                if (!cacheEntry.OriginalPoco.ContainsKey(col.Name))
                                {
                                    cacheEntry.OriginalPoco.Add(col.Name, value);
                                }
                            }
                        }
                    }
                    LazyLoadInjector.InjectLazyLoader <T>(poco, _ctx, statement._entityExecutedOn);
                }
                reader.Close();
                transaction.Commit();
                return(pocos);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
                Console.WriteLine("  Message: {0}", ex.Message);
                transaction.Rollback();
                throw ex;
            }
        }