[C# MySQL] NoNullAllowedException

Pagina: 1
Acties:

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ik heb in C# een tableadapter geschreven.
Deze laad na het uitvoeren van FILL() de gegevens in een DataSet welke weer gebonden is aan een DataGridView.
code:
1
2
3
4
5
6
7
8
9
mysql> SELECT `hours_id`, `day`, `time_begin`, `time_end`, `time_break`, `users_id`, `activity_id` FROM `urenprog`.`hours`  WHERE (`activity_id` = 1) AND (`users_id` = 1);
+----------+------------+------------+----------+------------+----------+-------------+
| hours_id | day        | time_begin | time_end | time_break | users_id | activity_id |
+----------+------------+------------+----------+------------+----------+-------------+
|        1 | 2008-02-12 | 08:00:00   | 17:00:00 | 01:00:00   |        1 |           1 |
|       22 | 2008-05-22 | 08:00:00   | 08:00:00 | 01:00:00   |        1 |           1 |
|       21 | 2008-05-29 | 17:00:00   | 20:00:00 | 00:00:00   |        1 |           1 |
+----------+------------+------------+----------+------------+----------+-------------+
3 rows in set (0.01 sec)

Door middel van `activity_id` en `users_id` kan men een gebruiker selecteren en de activiteit waar de uren voor staan. (werk bijvoorbeeld).
Voor het gemak heb ik hier even voor allebij 1 ingevuld.

In het DataGridView laat ik alle kolommen zien BEHALVE `hours_id`, `users_id` en `activity_id`

Het probleem komt nu op het moment dat ik een waarde in wil voeren.
Er worden 3 kolommen niet getoond en als ik in mijn datagridview informatie in wil voeren krijg ik vervolgens een System.Data.NoNullAllowedException.

De kolom `hours_id` mag geen null bevatten.
Dit wil ik echter wel aangezien als bij het invoeren van de data dan netjes een nieuwe waarde toegewezen word (AUTO_INCREMENT).

Nu moet dit volgens microsoft opgelost worden doorhet volgende:
Set AllowDBNull to true.
Setting this property to true will allow you to inset null values. For more information, see AllowDBNull.
Maar mijn het schema van de tabel in mijn DataSet word automatisch aangemaakt tijdens FILL().

Nu is mijn vraag dus:
Hoe kan ik in code van te voren aangeven hoe mijn tabel er uit komt te zien in de dataset zodat ik op de kolom `hours_id` de property AllowDBNull op true kan zetten.
Zoiezo kom ik er niet echt uit hoe ik zelf de tabel opbouw in de dataset zodat de mysql gegevens daar netjes inkomen.
En is dit eigenlijk wel nodig of kan ik na het genereren van de tabel in de dataset alsnog de?/het? property van de kolom op true zetten?


Afbeeldingslocatie: http://www.vanweenen.net/~joost/afbeeldingen/foutmelding.png
Afbeeldingslocatie: http://www.vanweenen.net/~joost/afbeeldingen/voorbeeld2.png

[ Voor 57% gewijzigd door Gehakt op 14-06-2008 02:20 . Reden: Heb de verouderde code verwijderd ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
Je zal er moeten voor zorgen dat je auto-increment van die datatablecolumn ook gezet is (maar dan aflopend bv), en er voor zorgen dat, bij het bewaren alles netjes gesynched wordt.

Je kan trouwens ook gebruik maken van typed datasets ...

https://fgheysels.github.io/


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Aha de column kan dus ook auto-increment hebben. Dat is handige info. Maar dan blijft mijn vraag staan . Waar in mijn code defineer ik dat en waarom doet MySQL dat niet op het moment dat hij het tabelschema maakt?
Lijkt me een bug eigenlijk.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
Waarom zou dat een bug zijn ?
Waarom zou je per definitie willen dat je column in je dataset ook auto-inc is als je gegevens in je dataset laadt, ook al geef je aan dat het schema moet gemaakt worden ?
Waar geef je dat aan in je code ? Kijk eens naar de members van DataColumn (of hoe heet die class ook alweer die een column in je datatable voorstelt).

Als je dat allemaal wil, en je blijft met datasets werken, waarom maak je dan geen gebruik van typed datasets ?

https://fgheysels.github.io/


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ik bedoel meer. Mysql maakt op dit moment het schema van mijn tabel in de dataset. In mysql is Hours_id mijn primary key en heeft ook auto_increment. Waarom zou dat in de column van mijn dataset tabel dan niet zo zijn?

Verder is mijn vraag dan ook. Hoe zorg ik dat het wel goed gaat.
Ik weet wel dat ik DataColumn de AllowDBNull property kan geven.
Maar niet waar of wanneer ik dit in mijn code moet doen?!

Naar ik begrijp zijn er 2 manieren:
1. Mysql maakt de tabel.
2. Je defineert zelf je dataset tabel en zorgt dat de gegevens van mysql daar netjes inkomen.

Manier 1 gebruik ik op dit moment maar ik weet dan niet op welk moment in de code ik de tabel column aan moet passen?
Manier 2 lijkt mij het beste maar ik weet uberhaupt niet hoe dat moet? Waar kan ik hier voorbeelden van vinden?

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
Manier 2 lijkt mij het beste maar ik weet uberhaupt niet hoe dat moet? Waar kan ik hier voorbeelden van vinden?
google ? MSDN ?
Als je mijn post leest, weet je al waar je naar moet zoeken ...

https://fgheysels.github.io/


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 17-11 21:39

mulder

ik spuug op het trottoir

Als je hours_id nou gewoon uit je INSERT query weglaat?

oogjes open, snaveltjes dicht


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Dat werkt niet.
Ik heb ook al geprobeerd handmatig "NULL" in de query te zetten.
De Query is dan wel geldig maar het gaat fout tussen het invoeren van een nieuwe row in het datagridview die in de dataset word gezet.
Dit heeft dus eigenlijk nog niets met MySQL te maken krijg ik het idee.

Ik ben nu hard aan het zoeken naar typed datasets en hoe ik deze in mijn code kan gebruiken.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
Als je in je tabel een veld 'id' hebt, dat een auto-increment veld is, dan werkt dit wel
code:
1
2
3
4
INSERT INTO tabel 
(naam)
VALUES
("melp")

Je nieuwe record zal dan geinsert worden, en je ID column zal automatisch ingevuld worden.
Ik heb ook al geprobeerd handmatig "NULL" in de query te zetten.
Dat gaat idd niet ...

https://fgheysels.github.io/


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
whoami schreef op vrijdag 13 juni 2008 @ 18:52:
[...]

Als je in je tabel een veld 'id' hebt, dat een auto-increment veld is, dan werkt dit wel
code:
1
2
3
4
INSERT INTO tabel 
(naam)
VALUES
("melp")

Je nieuwe record zal dan geinsert worden, en je ID column zal automatisch ingevuld worden.

[...]
Dat gaat idd niet ...
code:
1
2
mysql> INSERT INTO `urenprog`.`hours` VALUES(NULL, '2008-01-01', '08:00:00', '17:00:00', '01:00:00', 1,1);
Query OK, 1 row affected (0.00 sec)
Dat snap ik. Maar persoonlijk vul ik dan nog steeds liever alle waardes in. In dit geval stuur ik dan gewoon NULL mee en dit werkt prima zoals je ziet.
Ik ben er ook achter dat mijn probleem niet zozeer met MySQL te maken heeft als wel met DataGridViews en mijn DataSet.

[ Voor 7% gewijzigd door Gehakt op 13-06-2008 19:22 ]


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Gehakt schreef op vrijdag 13 juni 2008 @ 19:21:
[...]

code:
1
2
mysql> INSERT INTO `urenprog`.`hours` VALUES(NULL, '2008-01-01', '08:00:00', '17:00:00', '01:00:00', 1,1);
Query OK, 1 row affected (0.00 sec)
Dat snap ik. Maar persoonlijk vul ik dan nog steeds liever alle waardes in. In dit geval stuur ik dan gewoon NULL mee en dit werkt prima zoals je ziet.
Ik ben er ook achter dat mijn probleem niet zozeer met MySQL te maken heeft als wel met DataGridViews en mijn DataSet.
Maar waarom vul je liever andere waardes in, bij insert hoor je geen auto-increment waarden mee te geven dan ondermijn je gedrag van MySQL en maak je je queries trager. (immers moet mysql de waarde op veld Id die jij hebt gegeven eerst bekijken, dan bedenken of dat geldig is of dat het overschreven moet worden door auto_increment en dan pas de data laden, ipv meteen de overige data laden)

~ Mijn prog blog!


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ok ik word werkelijk gek van dit probleem. Het zal wel aan mij liggen maar ik kom er echt niet uit.
Ik heb nu zoals aangeraden een typed dataset gemaakt in de designer.
Hierin heeft de column `hours_id` AutoIncrement EN AllowDBNull.

Als ik:
dataGridView1.AutoGenerateColumns = true;
zet dan zie ik alle columns. Als ik dan een nieuwe waarde in wil voeren dan word `hours_id` netjes verhoogt.
Wat ik echter wil is dat dit achter de schermen gebeurd! Ik wil hours_id helemaal niet terugzien in mijn datagridview. Echter als ik zelf de columns van mijn DataGridView word er weer met deze error gesmeten.
Voor mij onbegrijpelijk omdat volgens mij dataset er toch echt de waarde null in mag staan.
Afbeeldingslocatie: http://www.vanweenen.net/~joost/afbeeldingen/voorbeeld3.png
Afbeeldingslocatie: http://www.vanweenen.net/~joost/afbeeldingen/voorbeeld4.png
Ik heb het idee dat het hier ook iets mee te maken heeft? Een andere waarde mag ik echter niet kiezen voor het datatype Int32 :|
Afbeeldingslocatie: http://www.vanweenen.net/~joost/afbeeldingen/voorbeeld5.png

Hieronder volgt de code die eventueel relevant kan zijn. Er missen dus delen. Hier zit ook de InsertQuery inderdaad niet bij omdat de fout al optreed voordat er ook maar iets met de insertquery gedaan word.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Diagnostics;
using MySql.Data.MySqlClient;

namespace MySQL
{
    public class Database
    {
        public MySqlConnection connection;
        public MySqlDataAdapter gegevensAdapter;
        public MySqlDataAdapter nameAdapter;
        public DataSet1 dataSet;

        public Database()
        {
            dataSet = new DataSet1();
        }

        public void CreateConnection()
        {
            connection = new MySqlConnection();
            connection.ConnectionString = "hierhoortdeconnectiestring";

            return;
        }

        public void CreateGegevensAdapter()
        {
            if (this.gegevensAdapter == null)
            {
                this.gegevensAdapter = new MySqlDataAdapter();
                this.gegevensAdapter.MissingSchemaAction = MissingSchemaAction.Error;

                gegevensAdapter.SelectCommand = new MySqlCommand("SELECT `hours_id`, `day`, `time_begin`, `time_end`, `time_break`, `users_id`, `activity_id` FROM `hours`  WHERE `activity_id` = ?activity_id AND `users_id` = ?users_id;", connection);

                MySqlParameter param;

                param = new MySqlParameter();
                param.ParameterName = "?activity_id";
                param.DbType = System.Data.DbType.Int32;
                param.MySqlDbType = MySql.Data.MySqlClient.MySqlDbType.Int32;
                param.IsNullable = true;
                param.SourceColumn = "activity_id";
                gegevensAdapter.SelectCommand.Parameters.Add(param);

                param = new MySqlParameter();
                param.ParameterName = "?users_id";
                param.DbType = System.Data.DbType.Int32;
                param.MySqlDbType = MySql.Data.MySqlClient.MySqlDbType.Int32;
                param.IsNullable = true;
                param.SourceColumn = "users_id";
                gegevensAdapter.SelectCommand.Parameters.Add(param);    
            }
            return;
        }


        public void GetGegevens(Int32 activity_id, Int32 users_id)
        {
            // Tijdelijke waarden
            activity_id = 1;
            users_id = 1;
            this.gegevensAdapter.SelectCommand.Parameters["?users_id"].Value = users_id;
            this.gegevensAdapter.SelectCommand.Parameters["?activity_id"].Value = activity_id;
            this.connection.Open();
            this.gegevensAdapter.Fill(this.dataSet, "Gegevens");
            this.connection.Close();
            return;
        }


    }
}

[ Voor 67% gewijzigd door Gehakt op 14-06-2008 03:16 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
NullValue is de waarde die je krijgt als je een veld wilt uitlezen dat op NULL staat.
Als je dat op throw exception gooit, en je doet dit:
code:
1
int id = row.Id

En row.Id is null, dan wordt er een exceptie gegooid.
Zet je de NullValue op -1, dan zal id -1 krijgen als waarde bv. Vreemd dat je zegt dat je daar geen andere waarde kunt inzetten; ik deed het vroeger wel altijd via de XML view, en daar kan je gewoon 'codegen:nullValue=-1' zetten bv.

De exceptie die je krijgt, heeft trouwens met users_id te maken, en niet met hours_id (waarmee je nu loopt te pielen).
Ik kan me voorstellen dat users_id in die tabel geen auto-increment is ...

https://fgheysels.github.io/


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Je hebt inderdaad gelijk. Maar die 2 velden op auto_crement zetten geeft vervolgens weer een probleem bij Fill() omdat dat parameters zijn die door de auto_increment waarden hebben gekregen die niet bestaan in de database. Ik heb mijn huidige code online gezet zodat als er mensen zijn die dit proberen op te lossen ze kunnen kijken of dit niet weer andere problemen oplevert, want ikzelf snap het echt niet meer. De code is nee, dat doen we niet ...
whoami schreef op zaterdag 14 juni 2008 @ 10:24:
Vreemd dat je zegt dat je daar geen andere waarde kunt inzetten; ik deed het vroeger wel altijd via de XML view, en daar kan je gewoon 'codegen:nullValue=-1' zetten bv.
Deze tip ga ik nog even proberen binnenkort. Toch vind ik het raar dat het niet mag via de GUI en ik dat het dan wel zou compilen als ik het handmatig aanpas, maar ik ga het zeker proberen.

Ik zit dit weekend even met werk en schooltoetsen maar ik hoop nog te reageren vandaag.

[ Voor 51% gewijzigd door whoami op 14-06-2008 12:13 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
Gehakt schreef op zaterdag 14 juni 2008 @ 12:08:
Je hebt inderdaad gelijk. Maar die 2 velden op auto_crement zetten geeft vervolgens weer een probleem bij Fill() omdat dat parameters zijn die door de auto_increment waarden hebben gekregen die niet bestaan in de database.
Ik zeg ook niet dat je die 2 velden op auto-incr moet zetten ?
't Is toch logisch dat, als je een nieuwe row in die ene table wil maken, dat je dat user-id moet invullen met het juiste id van de user ...

https://fgheysels.github.io/


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Dat is mij volkomen duidelijk. Echter:
  • Lijkt het mij ook logisch dat hours_id netjes zelf word ingevuld of opgehoogd. ZELFS als die column niet in het datagridview staat.
  • Snap ik niet waarom ik foutmeldingen krijg dat er null in `hours_id` staat bij het aanmaken van een nieuwe row als dit volgens mijn dataset WEL toegestaan zou moeten zijn.
  • Verder wil ik bij het invoegen van een nieuwe rij de kolommen activity_id en users_id vanuit een dropdownlist invullen. Wat zou het voor het datagridview uitmaken dat er niet direct een waarde word ingevuld? Lijkt mij dat dat niet zo'n probleem moet zijn zolang dit maar gedaan word voordat de Update() methode word aangeropen. En ook voor deze twee kolommen staat AllowDBNull gewoon op true.
Ik ga vanavond jouw tip proberen om de xml code zelf aan te passen en daar explicitiet in te zetten dat null waarden toegestaan zijn en dat mocht er niets ingevuld worden er dan gewoon de waarde null in moet komen te staan en er dus GEEN foutmelding gegooid word.

Geef mijn brakke C# code er de schuld maar van maar tot nog toe is er niemand die de gouden tip hier voor heeft of mij verteld dat de opzet die ik wil uberhaupt te debiel voor woorden is.

No offence whoami. Ik waardeer je hulp echt heel erg maar als je heel lang tegen een probleem aanstaard kan je er echt gek van worden. Vooral op het moment dat je het idee heb dat het gewoon zou moeten werken.
Ik bedoel. Waarom zou ik de NullValue property van een Int32 column niet gewoon op null mogen zetten? |:(
Dan komt visual studio met het volgende aanzetten:
The value entered is not valid for the current data type.
Dan vraag ik me echt af...maar WAAROM dan?

[ Voor 3% gewijzigd door Gehakt op 14-06-2008 18:54 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
maar waarom wil je daar NULL kunnen inzetten ?
Die nullValue wordt enkel gebruikt als je de waarde van een column die op NULL staat, wilt uitlezen.

Jij wil een record inserten; jij moet er gewoon voor zorgen dat die auto-increment goed gezet wordt in je DB (daar zijn imho een hoop tutorials voor te vinden), en je moet er gewoon ook voor zorgen dat nieuwe records die je maakt via je DataGridView de juiste waarde krijgen in 'users_id', voordat die nieuwe row aan de datatable wordt toegevoegd....

Kan je hier niets mee
klik
klik
klik

https://fgheysels.github.io/


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Volgens mij snap je mijn probleem nog niet helemaal helaas. Ik ben er namelijk achter gekomen dat het probleem helemaal niks met de database te maken heeft.
Het gaat fout tussen de DataSet en het DataGridView.
Ik laat 3 kolommen NIET ZIEN in mijn DataGridView.
Op het moment dat ik dan een nieuwe row wil maken. Vult de DataGridView de missende columns met null blijkbaar.
Echter treed er dan een error op omdat dat niet zou mogen.
Wat gelul is aangezien in mijn dataset de property AllowDBNull gewoon op True staat!
Vervolgens wil ik de NullValue property op null zetten IPV op "Throw Exception".
Dit mag vervolgens weer niet om de een of andere reden.

Dus om even het probleem duidelijk te maken.
Het gaat dus er dus om dat bij het aanmaken van een nieuwe row in mijn datagridview de missende colums de waarde null krijgen wat schijnbaar niet mag.

De 3 colums die ontbreken in mijn datagridview zijn:
  1. hours_id: Het boeit mij helemaal niet wat hier in staat want ik wil die bij het inserten in de database niet eens defineren. Zoals je zelf al aangaf is dat niet nodig want dat doet mysql zelf. Op het moment dat er een nieuwe rij aangemaakt word in het datagridview en word in deze column automatisch null gezet en een exception gegenereerd. Hij zou in de dataset op autoincrement mogen MAAR! autoincrement gebeurt alleen als de column ook zichtbaar is in de datagridview (wat ik dus helemaal niet wil).
  2. users_id: deze column wil ik voor het inserten een waarde toekennen vanuit een andere bron. Bijvoorbeeld een dropdownlijst.
  3. activity_id: zie het geval hierboven.
Hopelijk is het probleem nu duidelijker. Het heeft nog niets met de database te maken maar met de dataset en de datagridview.

Ik sta ook open voor compleet andere voorstellen hoe ik het zou kunnen doen hoor.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
Ik heb het ook nergens gehad over je database .... Ik weet dat je probleem zit bij het toevoegen van een nieuwe row in je datatable (dat is dus nog niet je database) via je gridview.
De exceptie die je krijgt (zie je screenshot van een paar posts eerder) gaat erover dat je je user_id niet gezet hebt. Dat moet je nu dus nog doen, en dan is je probleem opgelost.
Je kan bv misschien gebruik maken van een BindingList en daar de AddingNew event oid gebruiken om die ID te zetten als je geen andere / betere manier weet ...

https://fgheysels.github.io/

Pagina: 1