web services - How do I update with a newly-created detached entity using NHibernate? -


explanation:

let's have object graph that's nested several levels deep , each entity has bi-directional relationship each other.

a -> b -> c -> d -> e 

or in other words, a has collection of b , b has reference a, , b has collection of c , c has reference b, etc...

now let's want edit data instance ofc. in winforms, use this:

var instanceofc;  using (var session = sessionfactory.opensession()) {     // instance of c id = 3     instanceofc = session.linq<c>().where(x => x.id == 3); }  sendtouiandletuserupdatedata(instanceofc);  using (var session = sessionfactory.opensession()) {     // re-attach detached entity , update     session.update(instanceofc); } 

in plain english, grab persistent instance out of database, detach it, give ui layer editing, re-attach , save database.

problem:

this works fine winform applications because we're using same entity throughout, difference being goes persistent detached persistent again.

the problem i'm using web service , browser, sending on json data. entity gets serialized string, , de-serialized new entity. it's no longer detached entity, rather transient 1 happens have same id persistent 1 (and updated fields). if use entity update, wipe out relationship b , d because don't exist in new transient entity.

question:

my question is, how serialize detached entities on web client, receive them back, , save them, while preserving relationships didn't explicitly change? know isession.saveorupdatecopy , isession.merge() (they seem same thing?), still wipe out relationships if don't explicitly set them. copy fields transient entity persistent entity 1 one, doesn't work when comes relationships , i'd have handle version comparisons manually.

i solved problem using intermediate class hold data coming in web service, copying properties database entity. example, let's have 2 entities so:

entity classes

public class album {     public virtual int id { get; set; }     public virtual icollection photos { get; set; } }  public class photo {     public virtual int id { get; set; }     public virtual album album { get; set; }     public virtual string name { get; set; }     public virtual string pathtofile { get; set; } } 

album contains collection of photo objects, , photo has reference album it's in, it's bidirectional relationship. create photodto class:

dto class

public class photodto {     public virtual int id { get; set; }     public virtual int albumid { get; set; }     public virtual string name { get; set; }     // note dto not have pathtofile property } 

now let's have following photo stored in database:

server data

new photo {     id = 15,     name = "fluffy kittens",     album = session.load<album>(3) }; 

the client wants update photo's name. send on following json server:

client data

put http://server/photos/15

{     "id": 15,     "albumid": 3,     "name": "angry kittens" } 

the server deserializes json photodto object. on server side, update photo this:

server code

var photodto = deserializejson(); var photodb = session.load(photodto.id); // or use id in url  // copy properties photodto photodb photodb.name = photodto.name; photodb.album = session.load<album>(photodto.albumid);  session.flush(); // save changes db 

explanation

this best solution i've found because:

  1. you can choose properties client allowed modify. example, photodto doesn't have pathtofile property, client can never modify it.

  2. you can choose whether update property or not. example, if client didn't send on albumid, 0. can check , not change album if id 0. likewise, if user doesn't send on name, can choose not update property.

  3. you don't have worry lifecycle of entity because retrieved , updated within scope of single session.

automapper

i recommend using automapper automatically copy properties dto entity, if entites have lot of properties. saves trouble of having write every property hand, , has lot of configurability.


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -