Neo NET Entity Objects http neo codehaus org
Neo . NET Entity Objects http: //neo. codehaus. org Architecture and Implementation Copyright © 2002 -2004 Erik Dörnenburg – Last updated: December 2004
Neo Architecture and Implementation • The Big Picture • System. Data integration • Overview of the main classes • More gory details
Neo Architecture: The Big Picture The Entity Object world and the ADO. NET world are brought together by Composition Data. Set * Object. Context Data. Table * Data. Row Entity. Object Author. Base Author *
Neo Impl: ADO. NET integration Every entity object has a reference to its Data. Row and to the context it belongs to. public class Entity. Object { public Data. Row { get { … }; } public Object. Context { get { … }; } Data is stored in directly in row: public string First. Name { set { Row["au_fname"] = value; } get { return Row["au_fname"]; } Note how property names and column names can be mapped.
Neo Impl: ADO. NET integration To-one relation properties take the value from the related object and set it as foreign key value public class Title { public Publisher { set { Row["pub_id"] = value. Row["pub_id"]; } They use the context to find the object for the foreign key value in the related table get { return (Publisher)Context. Get. Object("publishers", Row["pub_id"]); }
Neo Impl: ADO. NET integration To-many relations are managed by and exposed as typed collections public class Publisher { public readonly Title. Relation Titles; The relation collection objects have a reference to the object that owns the relation and a cache for the objects in the relation Entity. Object Publisher. Base Publisher Object. Coll'Base (*) * Entity. Object. Rel'Base Title. Relation Title
Neo Impl: ADO. NET integration Relation objects work much like the relation properties. They manipulate the foreign key column of the affected object. public void Add(Title a. Title) { a. Title. Row["pub_id"] = Owner. Row["pub_id"]; } public void Remove(Title a. Title) { a. Title. Row["pub_id"] = null; } and use the context to find objects protected void Load() { inner. List = Owner. Context. Get. Objects( … );
Neo Architecture: The Big Picture The Entity Object world and the MS. NET world are brought together by Composition Data. Set * Object. Context Data. Table * Data. Row Entity. Object Author. Base Author *
Neo Architecture: The Object Context Applications create as many contexts as required. context = new Object. Context(); Object. Context actually handles all of the CRUD operations, other methods are just a façade. public Class Object. Context { IEntity. Object Create. Object(Type object. Type); IList Get. All. Objects(Type object. Type); IList Get. Objects( … ); void Delete. Object(IEntity. Object an. Object);
Neo Architecture: The Object Context The context relies on its internal Data. Set to track changes (creates, updates and deletes. ) It provides methods to save or get the changes. public ICollection Save. Changes(); public void Get. Changes(); Data can be added from other ADO. NET classes context. Merge. Data. Set(a. Data. Set); context. Import. Row(a. Data. Row); Factories create entity objects in a specific context; they use the context passed to the constructor. author. Factory = new Author. Factory(my. Context);
Neo Architecture: Data Stores A data store is responsible for retrieving and updating the backing store for the context. public interface IData. Store { Data. Table Fetch(IFetch. Specification fs) ICollection Save(Data. Table table) void Begin. Transaction() … Object. Context uses a data store to retrieve objects and save changes. A special data store could act as a façade for other data stores. I could select an appropriate store for a request and forward the request.
Neo Architecture: Disconnected clients Object contexts can work without a data store and take data directly from a Data. Set. context = new Object. Context(some. Data. Set); They allow indirect access to their internal Data. Set so that changes can be made persistent. ds = context. Get. Changes(); // do something to persist these changes, // maybe send dataset to a server. . . if(success) context. Accept. Changes();
Neo Architecture: Pk. Change. Table Used to redistribute database generated keys. Neo generates temporary (negative) primary key values. Data stores provide a mapping from these temporary keys to the actual db values. table = new Pk. Change. Table("jobs"); table. Add. Pk. Change(row["job_id"], actual. Key. Val); Use in distributed environments: changes = client. Context. Get. Changes(); server. Context. Merge. Data. Set(changes); pkct. Array = server. Context. Save. Changes(); client. Context. Update. Primary. Keys(pkct. Array); client. Context. Accept. Changes();
Neo Architecture: Main classes Entity. Object. Context Object. Coll'Base Object. Factory Pk. Change. Table Object. Rel'Base IData. Store Sql. Data. Store Oracle. Data. Store Firebird. Data. Store
Neo Neo. Core and IEntity. Object and a specific constructor are the minimal interface for an entity object: public interface IEntity. Object { Neo. Core. Object. Context { get; } System. Data. Row { get; } } public Some. Class(Data. Row row, Object. Contect ctx) All core classes use IEntity. Object only and do not impose the Entity. Object/Base/User Class structure. Consequently, Neo. Core could be used to implement alternative entity object models.
Neo Internals: IFetch. Specification is used to select objects in object contexts and data stores. public interface IFetch. Specification { public IEntity. Map { get; } public Qualifier { get; } } Fetch. Specification is a straight-forward impl public class Fetch. Specification : IFetch. Spec… { public Fetch. Specification(IEntity. Map m, …) } Query Templates implement IFetch. Specification.
Neo Internals: IEntity. Map Provides information about the mapping between database tables and entity objects. public interface IEntity. Map { Type Object. Type { get; } string Table. Name { get ; } string[] Columns { get; } string Get. Column. For. Property(string prop); Can generate ADO. NET schema information. void Update. Schema(Data. Table table, …) Neo provides an abstract implementation that is subclassed by generated classes, one per entity. This is likely to change; always use interface.
Neo Internals: IEntity. Map. Factory Entity map factories provide access to entity maps by table name or object type. public interface IEntity. Map. Factory { IEntity. Map Get. Map(string table. Name); IEntity. Map Get. Map(Type object. Type); ICollection Get. All. Maps(); } Default. Entity. Map. Factory is standard implementation that searches for IEntity. Map implementers in all linked assemblies.
Neo Internals: IPk. Initializer Contains a single method which must initialise a new database row. If scheme involves pk values provided by the application they are passed in. public interface IPk. Initializer { void Initialize. Row(Data. Row row, object arg); } Neo has 5 implementations. public class User. Pk. Initializer public class Native. Pk. Initializer public class Guid. String. Pk. Initializer public class New. Guid. Pk. Initializer
- Slides: 19