private void Update(DatabaseObject obj)
        {
            if (obj.NewlyCreated)
            {
                throw new InvalidOperationException("Update of object newly created.");
            }

            if (!obj.Dirty)
            {
                return;
            }

            obj.Validate();

            var updates = string.Join(", ",
                                      obj.Fields.Where(f => f.Dirty)
                                      .Select(f => f.ColumnName + " = " + f.VariableName));

            using (var command = Command("UPDATE {0} SET {1} WHERE id = @id", TableName(obj.GetType()), updates))
            {
                command.AddParam("@id", obj.Id.Value);

                foreach (var f in obj.Fields)
                {
                    if (f.Dirty)
                    {
                        f.AddValue(command);
                    }
                }

                command.ExecuteNonQuery();
            }

            obj.Updated();
        }
        private void CascaseLoad(DatabaseObject source, Dictionary <Guid, DatabaseObject> loaded)
        {
            foreach (var cascade in source.Cascades)
            {
                var assingList = new List <DatabaseObject>();

                foreach (var o in cascade.QueryLoad(this))
                {
                    if (!loaded.ContainsKey(o.Id))
                    {
                        loaded.Add(o.Id, o);
                        CascaseLoad(o, loaded);
                        assingList.Add(o);
                    }
                    else
                    {
                        assingList.Add(loaded[o.Id]);
                    }
                }

                cascade.AssignLoad(assingList);
            }

            foreach (var field in source.Fields)
            {
                foreach (var cascade in field.CascadeLoad())
                {
                    if (loaded.ContainsKey(cascade.Id))
                    {
                        cascade.AssignLoad(loaded[cascade.Id]);
                    }
                    else
                    {
                        var o = cascade.QueryLoad(this);

                        if (o != null && !loaded.ContainsKey(o.Id))
                        {
                            loaded.Add(o.Id, o);
                            CascaseLoad(o, loaded);
                        }
                    }
                }
            }

            source.Updated();
        }
        private void Insert(DatabaseObject obj)
        {
            if (!obj.NewlyCreated)
            {
                throw new InvalidOperationException("Insert of object not newly created.");
            }

            obj.Validate();

            var columns   = string.Join(", ", obj.Fields.Select(f => f.ColumnName));
            var variables = string.Join(", ", obj.Fields.Select(f => f.VariableName));

            using (var command = Command("INSERT INTO {0} ({1}) VALUES ({2})", TableName(obj.GetType()), columns, variables))
            {
                foreach (var f in obj.Fields)
                {
                    f.AddValue(command);
                }

                command.ExecuteNonQuery();
            }

            obj.Updated();
        }