Domanda

Sto cercando di capire come mantenere un oggetto utilizzabile tra le sessioni del cliente in DB4O. Da quello che ho capito, una volta chiusa una sessione del client, l'oggetto non risiede più in nessuna cache e nonostante il fatto di avere un UUID valido, non posso chiamare il negozio senza causare l'inserimento di un duplicato. Ho cercato un modo per nuovamente aggiornato alla cache, ma non esiste un tale meccanismo. Riorbirsi mi costringerà a copiare tutti i valori dall'oggetto ormai inutile.

Ecco il paragrafo sopra nel codice:

Person person = new Person() { FirstName = "Howdoyu", LastName = "Du" };
Db4oUUID uuid;

 // Store the new person in one session
using (IObjectContainer client = server.OpenClient())
{
    client.Store(person);
    uuid = client.Ext().GetObjectInfo(person).GetUUID();
}

// Guy changed his name, it happens
person.FirstName = "Charlie";

using (var client = server.OpenClient())
{
    // TODO: MISSING SOME WAY TO RE-USE UUID HERE

    client.Store(person); // will create a new person, named charlie, instead of changing Mr. Du's first name
}

L'ultima versione di Eloquera supporta questi scenari, tramite un attributo [ID] o tramite Store (UID, Object).

qualche idea?

È stato utile?

Soluzione 2

Ok, la risposta di Gamlor sul metodo db4o iextcontainer.bind () mi ha indicato la soluzione. Si noti che questa soluzione è valida solo in situazioni molto specifiche in cui l'accesso al DB è strettamente controllato e nessuna query esterna può recuperare le istanze degli oggetti.

ATTENZIONE: questa soluzione è pericolosa. Può riempire il tuo database con tutti i tipi di duplicati e oggetti spazzatura, perché sostituisce l'oggetto e non aggiorna i suoi valori, rompendo quindi qualsiasi riferimento ad esso. Clicca qui per una spiegazione completa.

AGGIORNARE: Anche in scenari strettamente controllati, questo può causare infiniti mal di testa (come quello che sto avendo ora) per qualcosa di diverso da un oggetto piatto con solo proprietà di valore (stringa, int, ecc.). A meno che tu non riesca a progettare il tuo codice per recuperare, modificare e salvare gli oggetti in una singola connessione DB4O, allora ti consiglio di non utilizzare affatto DB4O.

Person person = new Person() { FirstName = "Charles", LastName = "The Second" };
Db4oUUID uuid;

using (IObjectContainer client = server.OpenClient())
{
    // Store the new object for the first time
    client.Store(person);

    // Keep the UUID for later use
    uuid = client.Ext().GetObjectInfo(person).GetUUID();
}

// Guy changed his name, it happens
person.FirstName = "Lil' Charlie";

using (var client = server.OpenClient())
{
    // Get a reference only (not data) to the stored object (server round trip, but lightweight)
    Person inactiveReference = (Person) client.Ext().GetByUUID(uuid);

    // Get the temp ID for this object within this client session
    long tempID = client.Ext().GetID(inactiveReference);

    // Replace the object the temp ID points to
    client.Ext().Bind(person, tempID);

    // Replace the stored object
    client.Store(person);
}

Altri suggerimenti

Questa funzionalità manca davvero in db4o = (. Ciò rende DB4O molto difficile da usare in molti scenari.

Fondamentalmente devi scrivere il tuo metodo REATTACH affrontando tutti gli attributi. Forse una biblioteca come Automapper può aiutare, ma alla fine devi farlo da solo.

Un'altra domanda è se vuoi davvero usare gli Uuidi DB4O per identificare un oggetto. Gli uuidi DB4O sono enormi e non un tipo ben noto. Personalmente preferirei normali Guid .net.

A proposito: esiste il metodo db4o .bind (), che lega un oggetto a un ID esistente. Tuttavia non fa quasi quello che vuoi veramente. Immagino che tu voglia archiviare le modifiche apportate a un oggetto. Bind sostanzialmente sostituisce l'oggetto e rompe il grafico degli oggetti. Ad esempio, se si dispone di oggetti parzialmente caricati e quindi leggi, perdi riferimenti agli oggetti. Quindi .Bind non è utilizzabile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top