Laden...

Retina.NET: NullReferenz mit GeneratorId

Letzter Beitrag vor 17 Jahren 20 Posts 2.504 Views
Retina.NET: NullReferenz mit GeneratorId

Hallo,

hat hier jemand Erfahrungen mit Retina.Net?

Ich hab leider schon mit dem Quickstart Beispiel das Problem, dass es nicht so funktioniert wie angegeben, weil das Feld auf dem IsKey=true definiert ist, readonly sein muss.

Und wenn ich das dann readonly mache, scheiterts beim Persist() an einer retina-internen Nullreferez, zu der ich keine weitere Info finde.

Das passiert mir mit Retina 2.0.0.0, 1.0.8.0 und 1.0.7.7.

Witzigerweise kann ich eigene Klassen persisten, sobald ich den Key im konstructor selbst setzt und keine Generators verwende...

Besonders viel Dokumentation ist leider auch nicht vorhanden, sodass ich langsam doch eher zu NHibernate tendiere (was ich mir eigentlich ersparen wollte).

Eigentlich schade, da Retina vom Konzept her gut aussieht, und mit dem Attribut basierten Mapping einfacher zu bedienen wäre.

loop:
btst #6,$bfe001
bne.s loop
rts

Ich kenne Retina recht gut, wenn auch die Version, die ich einsetze in grossen Teilen
nicht mehr dem Orginal entspricht 😉

Das mit den generatoren ist aber recht simple.

Welchen der beiden setzt Du denn ein?
IdentityGenerationLocation.Repository bedeutet, das deine Datenbank dieses Feld besetzt,
also meist eine Autowert spalte ( Identity ) ist.

IdentityGenerationLocation.Entity bedeutet, das Du in IdGeneratorTyp
eine Klasse spezifizieren musst, die IdGenerator implemnentiert.

Wenn Du mal im Unittest Verzeichnis die Datei IntIdGenerator.cs anschaust, siehst Du wie es geht.

naja ich hab schon ein paar sachen probiert die auch funktionieren, aber grad das beispiel aus dem quickstart geht eben nicht so wies steht (auch das exakte copy paste mit connectionstring anpassung funzt nicht.

wenn ich die Id nicht vom generator setzen lasse, gehts wie gesagt.

das original beispiel bzw mein angepasster test verwendet den IdGeneratorGuid:


[TypeStorage]
public class MyTestClass : Entity
{
    public MyTestClass()
    {
    }

    [FieldStorage(IsKey = true, IsIdentity = true, IdGeneratorType = typeof(IdGeneratorGuid), IdGeneratorLocation= IdentityGenerationLocation.Entity)]
    public readonly Guid Id;

    [FieldStorage]
    public string Description = "";
}


[TestFixture]
public class RetinaTest
{
    private readonly string _connectionString = @"...";

    private IDataStore _store;
    private IDataStoreBroker _broker;

    [Test]
    public void TestClassTest()
    {
        _store = new SqlDataStore(_connectionString);
        _store.GetBuilder().CreateTable(typeof(MyTestClass), true);

        MyTestClass obj = new MyTestClass();
        obj.Description = "Hello world!";

        _broker = new DataStoreBroker(_store);

        _broker.Persist(obj);
    }
}

der table wird richtig erzeugt.
aber beim obj.Persist() stellts ihn mit der retina internen nullreferenz auf:

Retina.RetinaCriticalException: Unexpected critical exception occurred. Please check the inner exception for more details. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei Retina.DataStore.BaseDataStore.GetQualifiedName(String name)
bei Retina.BaseEntityPersister.GetInsertCommand(IDataStore dataStore, EntityStorageDefn entityDef)
bei Retina.BaseEntityPersister.Persist(ITxnContext txnContext, Object appContext, Entity entity, EntityStorageDefn entityDefn)
bei Retina.BaseEntityPersister.Persist(ITxnContext txnContext, Object appContext, Entity entity)
bei Retina.DataStoreBrokers.InternalDataStoreBroker.Persist(ITxnContext txnContext, Object appContext, Entity entity)
bei Retina.DataStoreBrokers.Department.TxnContext.Persist(Object appContext, Entity entity)
bei Retina.DataStoreBrokers.Department.DataStoreBroker.Persist(Object appContext, Entity entity)
--- Ende der internen Ausnahmestapelüberwachung ---
bei Retina.DataStoreBrokers.Department.DataStoreBroker.Persist(Object appContext, Entity entity)
bei Retina.DataStoreBrokers.BaseDataStoreBroker.Persist(Entity entity)
bei MiP.Unitis.Web.Test.Database.DatabaseTest.TestClassTest() in D:\Dev\Unitis\Unitis.Web.Test\Database\DatabaseTest.cs:Zeile 93.

bin wahrscheinlich schon zu blind um den fehler zu sehen...

eingebundene referenzen:
Retina.Core
Retina.DataStore.MsSql
Retina.DataStore.MsSql2005
(den rest ebenfalls einzubinden hat bisher nichts gebracht)

loop:
btst #6,$bfe001
bne.s loop
rts

werd retina wohl auf debug kompilieren und selber reinschauen müssen...

loop:
btst #6,$bfe001
bne.s loop
rts

Uhh, das mit dem Connectionstring war ein böser Fehler in Retina, das geht nämlich überhaupt nicht.

Es fehlt das Parsen in die internen Datenstrukturen.

du meinst ich darf die überladung mit dem connectionstring nicht verwenden sondern muss eine andere zb.


new SqlDataStore("server" "database") 

verwenden?

*gronf* 😁

werd ich nach der arbeit probieren,
danke

loop:
btst #6,$bfe001
bne.s loop
rts

Ja, oder eben das Parsen im Constructor selber machen 😭

Ich habe wirklich massiv aufgeräumt, da ich das Prinzip von Retina deutlich besser fand,
und Gentle.NET nicht so prickelnd fand.

Es sind da einige Kinken drin, wenn man z.B. einen neuen Provider für SqlCompact macht,
der OleDB funktioniert nicht auf anhieb, Das validieren kostet zuviel zeit.....

Wenn ich mal Zeit habe werde ich dem Author mal eine lange liste schicken.

Hab retina auch ausprobiert, weil mir bei gentle noch zu viel fehlt.

bis dlinq dauerts leider noch ein weilchen.

loop:
btst #6,$bfe001
bne.s loop
rts

Hallo 0815Coder,

...und mit dem Attribut basierten Mapping einfacher zu bedienen wäre.

Mit dem noch nicht releasedem NHibernate 1.2. geht das doch wunderbar. So zumindest mein erster Eindruck.

Und nix da mehr mit externen hbm.files, wenn man diese nicht möchte.
Das Thema NHibernate 1.2.x wird in einem Artikel in der letzten Dot.Net behandelt.

Gruß falangkinjau

Ja, und hast Du dir angeschaut wie die das machen?

Da wird dann beim Programmstart die hbm-Mappingdatei generiert.
Ist echt ein fortschritt.

Hallo FZelle,

naklar habe ich mir das angeschaut und ausprobiert.

Generiert wird dann aber über ein MemoryStream! Sofern gewünscht.

Also, ich finde das schon einen kleinen winzigen Fortschritt.

  1. Die hbm.files müssen nicht mehr extra eingetippt werden und müssen nicht als embedded Resource bzw. physisch vorliegen.
  2. Sie werden für den Anwender(Entwickler) einfach nicht mehr benötigt.

Wie Praxistauglich das dann alles sein wird keine Ahnung. Schauen wir mal.

Gruß falangkinjau

Am Constructor lags leider nicht, passiert auch mit den anderen overloads... muss mich da mal mehr reinhängen um was brauchbares rauszubekommen.

loop:
btst #6,$bfe001
bne.s loop
rts

Benutzt Du Access?
Das funktioniert fast überhaupt nicht mit dem Orginal.
Wenn Du den Sql-Server2005 benutzt geht es schon eher.

Ich kann mal am WE meine gesammten Arbeiten zusammenpacken
( ich habe da eine DLL draus gemacht mit allen Providern, Helpern.... )
und mal eine kleine Demo dazu machen, wenn es hift 😉

nein, ich verwend den sql2005 (express - wenns am express geht wirds wohl am großen bruder auch gehn.)

eine eigene klasse hab ich auch schon persisted und retrieved, allerdings hab ich da den key selber gesetzt, nicht mit generator. scheinbar haut bei den generatoren was nicht hin, obwohls eigentlich simpel ist gut genug beschrieben ist und auch genug beispiele drinn sind.

loop:
btst #6,$bfe001
bne.s loop
rts

Also bei mir gehen die.

Wie sieht denn deine Klasse zum persistieren mit Generator aus?


[TypeStorage]
public class MyTestClass : Entity
{
  public MyTestClass()
  {
  }

  [FieldStorage(IsKey = true, IsIdentity = true, IdGeneratorType = typeof(IdGeneratorGuid), IdGeneratorLocation = IdentityGenerationLocation.Entity)]
  public readonly Guid Id;

  [FieldStorage]
  public string Description = "";
}

wahlweise mit oder ohne
IdGeneratorLocation = IdentityGenerationLocation.Entity.

hab auch schon so probiert (gekürzt)


FieldStorage(IsKey = true, IsIdentity = true, IdGeneratorLocation = IdentityGenerationLocation.Repository)]
  public readonly int Id;

weil wenn ich einen Generator verwenden werde, wirds praktisch immer der AutoIncrement von SQL Server sein.

Ich verwende es komplett ohne Configuration, kanns daran liegen? Laut quickstart müssts ohne gehn (und teilweise gehts ja auch)

loop:
btst #6,$bfe001
bne.s loop
rts

Das ist einer der "kleineren" Fehler bei Retina.
Du musst die Tabelle Angeben, auf die Du das Object mappen willst.


[TypeStorage(TableName = "MyTestClass", VersionControl = EntityVersionControl.AllFields)]
	public class MyTestClass : Entity
	{
		public MyTestClass()
		{
		}

		[FieldStorage(IsKey = true, IsIdentity = true, IdGeneratorType = typeof(IdGeneratorGuid), IdGeneratorLocation = IdentityGenerationLocation.Entity)]
		public readonly Guid Id;

		[FieldStorage]
		public string Description = "";
	} 

Scheint so als müsst man ein paar der Fehler echt kennen, damit mans verwenden kann 😕

Im QuickStart ist das auch ohne den Tabellennamen...
Abgesehn davon dürfts dann den Constructor nicht geben...

puh...
Gibts irgendwo eine Liste auf der steht, was man nicht so verwenden darf, wie angegeben? g

loop:
btst #6,$bfe001
bne.s loop
rts

Klar, steht genau neben der liste der Reflection und MethodCompiler funktionen,
ca. 3 cm hinter dem linken präcortex lappen 😉

kannst mir den linken präcortex lappen mal kopieren? grins

es funktioniert jetzt übrigens,
vielen Dank.

loop:
btst #6,$bfe001
bne.s loop
rts