Is this how one would normally design classes?
One class = 1 Table.
How about tables that contain a foreign key to another table?
Suppose I have the following:
PersonTable
---------------
person_id
name
PersonMapTable
---------------
map_id
type_id (fk)
person_id
PersonTypeTable
-------------------
type_id
description
parent_type_id
AddressTable
-------------------
address_id
address1
address2
city
state
zip
AddressMapTable
-----------
address_map_id
address_id
person_id
Would good practice consist of creating a class for each table?
If so, what are the best practices for loading/saving such classes back to the database without an orm? A simple code example would be really helpful
I'd recommend reading Martin Fowler's Patterns of Enterprise Application Architecture, which has several patterns of mapping between classes and tables.
I don't think that one object per table is necessarily a good design. It's hard to give a one size fits all rule, but objects can be richer and more fine grained. A database can be denormalized for reasons that don't apply to objects. In that case, you'd have more objects than tables.
Your case would include 1:1 and 1:m relationships:
public class Person
{
// 1:m
private List<your.namespace.Map> maps;
}
public class Map
{
// 1:1
private your.namespace.Type;
}
For the most part I tend to map tables to entities, but it's not a hard rule. Sometimes there are instances where the repository for a specific entity in question is better off dealing with the general concerns surrounding a specific entity, which means it will cross into dealing with other tables as a result, without those tables specifically needing to exist as entities.
What I never do (except in very specific planned cases where the dependent data ALWAYS needs to be retrieved with the entity), is set an entity or collection of entities as a property of another entity. Instead, that entity will either be discoverable via its ID, which will either be a property of the parent entity or discoverable via the associated repository in relation to the parent entity.
In cases where I need the child entity or entities of another entity to be bundled together, I'll make use of an "info" helper class to pull together all the required data. For example, if I have an entity class Widget and it has a collection of child Part objects, then I would create a WidgetInfo class which would contain the Widget instance as a property and a collection of Part objects as the other property.
This way all entity classes remain as lightweight as they can and never make the assumption that dependent data will need to be loaded. Also it keeps the repository model clean without forcing you into messy ORM territory which is generally the case if you create child object collections on an entity class. If you do that without ORM, then you end up with the messy problem of when to load the children or not, and when to assume that the children have or have not been loaded.
I wouldn't say that I always have class per table, especially when you have many to many relationships. Based on your table above I would have 2 classes... I am not sure why you have both and id and a person_type_id, to me they would be the same thing but here are the classes.
Person
{
public int Id { get; set; }
public string Name { get; set; }
public List<PersonType> { get; set; }
}
PersonType
{
// I would discourage from using Type as property name as it is a keyword...
public string [Type] { get; set; }
}
Unless your users are data entry clerks, it's generally considered better to design classes from Use Cases/User Stories. Even if the database already exists.
Reason? It's too easy for users to end up assuming their job is to exercise the software, rather than expecting the software to help them do their jobs.
Clearly they need to intersect at some point. I concur that Fowler's book is a great place to start. But I think he'll reinforce this point of view.
If you want a modeling perspective that helps you get both the classes and the database right, consider Object Role Modeling.
If you plan on using Object-Relational Mapping (ORM), this may affect your table design. Hibernate, for instance, does not like mixed inheritance mapping strategies within the same tree.
Since you specifically indicated that you will not be using ORM, you can follow traditional database design principals. This typically means starting with one table per class, normalizing to third-normal form (read about database normalization here), then denormalizing to meet performance constraints (read about denormalization here).
Regarding your question about how to load and save the objects without the use of ORM, a common strategy is to use Data Access Objects (DAOs). Here is a simple example:
public interface ICustomerDao
{
public void insert(Customer customer) throws CustomerDaoException;
public void update(long id, Customer customer) throws CustomerDaoException;
public void delete(long id) throws CustomerDaoException;
public Customer[] findAll() throws CustomerDaoException;
public Customer findByPrimaryKey(long id) throws CustomerDaoException;
public Customer[] findByCompany(int companyId) throws CustomerDaoException;
}
You didn't specify which language you are using, but regardless you may find this example using Java generics for DAO useful.
Would good practice consist of
creating a class for each table? If
so, what are the best practices for
loading/saving such classes back to
the database without an orm?
You are using ORM. You are mapping objects to relational tables. Whether you use a pre-built library to do so or not is your call. If you don't, you'll be essentially implementing one yourself, though probably without all the bells and whistles of existing ORMs.
The two most common ways of doing this are the ActiveRecord pattern and the Data Mapper pattern. Each has its advantages and disadvantages.
With the ActiveRecord pattern, you define classes whose attributes define the table columns for you. Each instance of this class corresponds to a row in the database, and by creating (and saving) a new instance, you create a new row in the database. More information on that is available here: http://en.wikipedia.org/wiki/Active_record_pattern
In the Data Mapper pattern, you define table objects for each table, and write mapper functions which assign columns of the table to existing classes. SQLAlchemy uses this pattern by default (though there are ActiveRecord type extension modules, which adapt SQLAlchemy's functionality to a different interface. A brief introduction to this pattern can be found in SQLAlchemy's documentation here: http://www.sqlalchemy.org/docs/05/ormtutorial.html (read from the beginning up to but not including the section entitled, "Creating Table, Class and Mapper All at Once Declaratively;" that section explains ActiveRecord using SQLAlchemy).
The ActiveRecord pattern is easier to set up and get working with, and gives you classes which are clearly representative of your database, which has benefits in terms of readability. As a side benefit, the declarative nature of ActiveRecord classes effectively acts as clear and straightforward documentation for your database schema.
The Data Mapper pattern gives you far more flexibility in how your data maps to your classes, so you aren't tied to a more-or-less one-to-one relationship between tables and classes. It also separates your persistence layer from your business code, which means that you can swap out other persistence mechanisms later, if need be. It also means you can more easily test your classes without needing to have a database set up to back them.
For more in depth discussion of SQLAlchemy's mapper configuration, check out http://www.sqlalchemy.org/docs/05/mappers.html. Even if you aren't planning on using a library like SQLAlchemy, the documentation should help you see some of the options you may want to consider in mapping your classes to database tables.
This DataBase to Class point of view approach is more than likely to lead you to cranking lots of code quite quickly. However, a good chunk of this code will likely not be of any use or require some severe mutation. In other words, you'll likely build specific classes that mismatch your displays and workflow.
First, consider your apps, your users' needs, general workflow .. etc Actually come up with something that looks workable (i.e. mock your displays).
Concentrate on the classes you need to use the displays and model your storage (db design) after those needs. Chances are that you will have only a few of straight-table classes as most of your classes will naturally tend provide the solution for your displays.
Good luck.
Related
I read through Apress - Pro Asp.Net MVC 5 and the free chapters of the Identity Framework and now, I want to create a small sample application with some data and Identity.
Later I want to make a test deployment to Windows Azure.
Now, should I create one single Database for this Application, containing all Data (Products, whatsoever, IdentityData (User-Accounts, Oauth Linkings...)) or would it be better to create two Databases?
I know, If I'd create two, I would be able to use the same Identity-Data for other MVC Applications, but is there some kind of best practice for MVC?
There's no "best practice", per se, in this area. It depends on the needs of your individual application. What I can tell you is that if you choose to use multiple database, you'll end up with a somewhat fractured application. That sounds like a bad thing, but remember this is a valid choice in some scenarios. What I mean by that is simply that if you were to separate Identity from the rest of your application, requiring two databases and two contexts, there's no way, then, to relate your ApplicationUser with any other object in your application.
For example, let's say you creating a reviews site. Review would be a class in your application context, and ApplicationUser would of course be a class in your Identity context. You could never do something like:
public class Review
{
...
public virtual ApplicationUser ReviewedBy { get; set; }
}
That would typically result in a foreign key being created on the reviews table, pointing to a row in your users table. However, since these two tables are in separate databases, that's not possible. In fact, if you were to do something like this, Entity Framework would realize this problem, and actually attach ApplicationUser to your application context and attempt to generate a table for it in your application's database.
What you could do, though, is simply store the id of the user:
public string ReviewedById { get; set; }
But, again, this wouldn't be a foreign key. If you needed the user instance, you'd have to perform a two step process:
var review = appContext.Reviews.Find(reviewId);
var user = indentityContext.Users.Find(review.ReviewedById);
Generally speaking, it's better to keep all your application data together, including things like Identity. However, if you can't, or have a business case that precludes that, you can still do pretty much anything you need to do, it just becomes a bit more arduous and results in more queries.
My model layer has a pretty huge class hierarchy i.e. there are around 200 classes. The good/bad thing with the hierarchy is that all of them have the same base class (I am not talking about Object class here). The maximum distance between the base and leaf classes is 7 and the maximum number classes at any level in hierarchy is 80. I am using nHibernate to save/load data from persistent storage.
Problem The queries generated by nHibernate are pretty in efficient. The reason being that it tries to join tables that are not really needed in the query?
Has anyone used (n)Hibernate with such class hierarchy?
Please refer to NHibernate: Load base class objects only to see a specific example of one my problems.
NHibernate has to resort to that monster of a query because it did not know exactly which table contains the needed data. For example, with session.Get<Vehicle>(100), NHibernate does not know which table contains the data for the vehicle with ID 100, so it will have to join Vehicle, Car, Truck, Bicycle together. But with session.Get<Truck>(100), NHibernate know that data can only resided in Truck table, so the query will be much more efficient, with only one join: Vehicle and Truck.
So, if you cannot change your database schema, then I think you have only one option, namely trying to be as specific as possible when querying by always give NHibernate the exact type of entity you need.
If you can change your schema, then I think you should try to simplify the model classes, avoid such a large inheritance tree. NHibernate provides many other options to connect classes together.
Other option is to use One-to-one instead of joined-subclass to separate information of one domain model class into multiple classes without forcing them to inherit from each other. I have encountered the same problem with a much smaller inheritance tree (about 20 classes out of 150 classes share the same base class, and mapped using joined-subclass). When the family reaches 20-strong, I'm stop adding more class into the hierarchy if that's possible, and try to use One-to-One instead.
we have question about inheritance in PostgreSQL and mapping it as entities in JPA.
Our database, and tables we want to map are:
CREATE TABLE Answer (
idAnswer SERIAL,
answerContent VARCHAR,
idQuestion INTEGER,
version INTEGER,
CONSTRAINT Answer_idAnswer_PK PRIMARY KEY (idAnswer),
CONSTRAINT Answer_idQuestion_FK FOREIGN KEY (idQuestion) REFERENCES Question(idQuestion)
);
CREATE TABLE MatchAnswer (
matchingAnswer VARCHAR NOT NULL,
version INTEGER,
CONSTRAINT MatchAnswer_idAnswer_PK PRIMARY KEY (idAnswer)
) INHERITS(Answer);
CREATE TABLE TrueFalseAnswer (
isTrue BOOLEAN NOT NULL,
version INTEGER,
CONSTRAINT TrueFalseAnswer_idAnswer_PK PRIMARY KEY (idAnswer)
) INHERITS(Answer);
And we mapped them for entities using automatic tool in Netbeans 7.1.2.
At first I thought it would be enough just to add
#Entity
#Table(name = "truefalseanswer", catalog = "jobfairdb", schema = "public")
#XmlRootElement
public class Truefalseanswer extends Answer implements Serializable {
private static final
so just extends, but it didn't work properly.
What is the best approach to this? Thanks in advance.
JPA's concept of inheritance is based on ordinary tables. It doesn't really "get" the idea of PostgreSQL's table inheritance. That's one of the costs of working with a spec designed to expose the lowest common denominator of features and do so portably.
See this guide for a decent summary of JPA inheritance strategies. Note that in the newer Java 6 JavaDoc for #Inheritance there is a note saying that:
If the Inheritance annotation is not specified or if no inheritance
type is specified for an entity class hierarchy, the SINGLE_TABLE
mapping strategy is used.
... and if you look at how SINGLE_TABLE works, it's not surprising it doesn't work for you; it's expecting all subclasses to be in one big table with a magic discriminator value.
InheritanceType.TABLE_PER_CLASS is closer to how Pg behaves, but I suspect that the JPA impl will get a bit confused when the base type tables have entries for each entity of a leaf type. It tries to do things like UNION queries across the subclass tables when querying on the superclass, and that could produce odd results - at least duplication if UNION is used and performance issues if it uses UNION ALL. Depending on exactly how the provider implements the strategy it may work at least partially. You'd have to test, and the results would possibly be fairly provider specific.
A really good implementation of PG inheritance support for JPA would probably require JPA provider extensions for a new inheritance strategy that understood the PostgreSQL extensions for inheritance and for ONLY queries.
If you can convince your JPA implementation to use SELECT ... FROM ONLY subclass_table when in InheritanceType.TABLE_PER_CLASS mode then it should inter-operate OK with PostgreSQL inheritance. It would see only the non-inherited rows in each table and work with them as if they were ordinary tables. Your other non-JPA code could then keep using the inheritance features. I guess it's possible you could modify the PostgreSQL dialect code for Hibernate to do this, but personally I wouldn't go there unless I absolutely had to make JPA support existing PostgreSQL schema that relied heavily on inheritance.
There is a solution using MappedSuperClass annotation.
#MappedSuperClass
public abstract class AbstractAnswer{
#Id
protected Long idAnswer;
#Column(name="answerContent")
protected String answerContent;
}
#Entity
#Table(name="Answer")
public class Answer extends AbstractAnswer{
}
#Entity
#Table(name="MatchAnswer")
public class MatchAnswer extends AbstractAnswer{
protected String matchingAnswer;
}
#Entity
#Table(name="TrueFalseAnswer")
public class TrueFalseAnswer extends AbstractAnswer{
protected Boolean trueFalseAnswer;
}
Inheritance in Hibernate has nothing to do with PostgreSQL inheritance, even though both try to accomplish the same and might look the same.
The reason for this is that Hibernate takes the SQL standards as base, and adjusts the small specific features from each RDBMS. For instance, while MySQL have an "auto-increment" for sequential IDs, Oracle uses sequences.
Historically, data inheritance (or specialization) has been done by using separate tables for the specific fields, with primary-foreign-keys linking the tables together. In your example, MatchAnswer would have the ID as PK and FK to Answer.idAnswer. Same with TrueFalseAnswer (the ID is PK/FK to Answer.idAnswer).
The "inherits" definition that you posted is not (AFAIK) defined in any SQL standard, so, I'd be surprised if Hibernate supported this, specially because it seems to be something extremely specific to PostgreSQL and it seems it's a somewhat experimental feature: look at "Caveats" on the "Inheritance" chapter of the PostgreSQL documentation.
That said, I'd suggest to keep your data sane, mapping them according to the best relational-model practices. Then, in your Hibernate mappings, you can express data inheritance where it makes sense.
I need people's advice as to whether this the best way to achieve what I want. Apologies in advance if this is a little to subjective.
I want to use Entity Framework V.1 to create something similar to the following C# classes:
abstract class User
{
public int UserId;
public string TelephoneNumber;
}
class Teacher : User
{
public string FavorateNewspaper;
}
class Pupil : User
{
public string FavorateCartoon;
}
I need people's advice as to how to best to persist this information.
I plan to use SQL Server and the normal Membership Provider. It will create for me a table called aspnet_Users. There will be two roles: Teacher and Pupil.
I will add fields to the table aspnet_Users which are common to both roles. Then create tbl_Teachers and tbl_Pupils to hold information specific to one role.
So My database will look a bit like this:
aspnet_Users
int UserId
varchar TelephoneNumber
tbl_Teachers
int UserId
varchar FavorateNewspaper
tbl_Pupils
int UserId
varchar FavorateCartoon
The idea of course being that I can match up the data in aspnet_Users to that in either tbl_Teachers or tbl_Pupils by joining on UserId.
So to summarise, my questions are:
Is my database structure the best option to achieve these classes?
Should I try to wrap the Entities within my own POCO classes?
Should I change my database structure so that EF creates entities which are closer to the classes I want?
EDIT: I re-arranged my question it make it a bit clearer what I'm asking.
If you're using EF 1, then POCO can be a bit unpleasant. Unless there's a good reason not to, I'd just use normal EF entities. Your database model is fine, by the way, and is an example of TPT (Table Per Type) inheritance mapping. You could either use the wizard to create entites from the databaes, or create your entites and map them to the associated tables. If you do the former you'd initially end up with three unrelated entities. You'd then use the designer to tell EF that Pupil and Teacher inherit from User, and that User is abstract.
In general, one of the strengths of EF is that the entities don't have to match that closely to the tables that persist them. In this case though there's a natural mapping.
Okay, I'll be straight with you guys: I'm not sure exactly how Domain Driven my Design is, but I did start by building Model objects and ignoring the persistence layer altogether. Now I'm having difficulty deciding the best way to build my tables in SQL Server to match the models.
I'm building a web application in ASP.NET MVC, although I don't think the platform matters that much. I have the following object model hierarchy:
Property - has properties such as Address and Postcode
which have one or more
Case - inherits from PropertyObject
Quote - inherits from PropertyObject
which have one or more
Message - simple class that has properties Reference, Text and SentDate
Case and Quote have a lot of similar properties, so I also have a PropertyObject abstract base class that they inherit from. So Property has an Items property of type List which can contain both Case and Quote objects.
So essentially, I can have a Property that has a few Quotes and Cases and a load of Messages that can belong to either of those.
A PropertyObject has a Reference property (and therefore so do Quote and Case) so any Message object can be related back to a Quote OR Case by it's Reference property.
I'm thinking of using the Entity Framework to get my Models in and out of the database.
My initial thoughts were to have four tables: Property, Case, Quote and Message.
They'd all have their own sequential IDs, and the Case and Quote would be related back to Property by a PropertyID field.
The only way I can think of to relate a Message table back to the Case and Quote tables is to have both a RelationID and RelationType field, but there's no obvious way to tell SQL server how that relationship works, so I won't have any referential integrity.
Any ideas, suggestions, help?
Thanks,
Anthony
I am assuming Property doesn't also inherit from PropertyObject.
Given that these tables, Property, Case, Quote and Message, leads to a Table per Concrete Class or TPC inheritance strategy, which I generally don't recommend.
My recommendation is that you use either:
Table per Hierarchy or TPH - Case and Quote are stored in the same table with one column used as a discriminator, with nullable columns for properties that are not shared.
Table per Type or TPT - add a PropertyObject table with the shared fields and Case and Quote tables with just the extra fields for those types
Both of these strategies will allow you to maintain referential integrity and are supported by most ORMs.
see this for more: Tip 12 - How to choose an inheritance strategy
Hope this helps
Alex
Ahhh... Abstraction.
The trick with DDD is to recognize that abstraction is not always your friend. In some cases, too much abstraction leads to a too-complex relational model.
You don't always need inheritance. Indeed, the major purpose of inheritance is to reuse code. Reusing a structure can be important, but less so.
You have a prominent is-a pair of relationships: Case IS-A Property and Quote IS-A Property.
You have several ways to implement class hierarchies and "is-a" relationships.
As you've suggested with type discriminators to show which subclass this really is. This works when you often have to produce a union of the various subclasses. If you need all properties -- a union of CaseProperty and QuoteProperty, then this can work out.
You do not have to rely on inheritance; you can have disjoint tables for each set of relationships. CaseProperty and QuoteProperty. You'd have CaseMessage and QuoteMessage also, to follow the distinction forward.
You can have common features in a common table, and separate features in a separate table, and do a join to reconstruct a single object. So you might have a Property table with common features of all properties, plus CaseProperty and QuoteProperty with unique features of each subclass of Property. This is similar to what you're proposing with Case and Quote having foreign keys to Property.
You can flatten a polymorphic class hierarchy into a single table and use a type discriminator and NULL's. A master Property table has type discriminator for Case and Quote. Attributes of Case are nulled for rows that are supposed to be a Quote. Similarly, attributes of Quote are nulled for rows that are supposed to be a Case.
Your question "[how] to relate a Message table back to the Case and Quote tables" stems from a polymorphic set of subclases. In this case, the best solution might be this.
Message has an FK reference to Property.
Property has a type discriminator to separate Quote from Case. The Quote and Case class definitions both map to Property, but rely on a type discriminator, and (usually) different sets of columns.
The point is that the responsibility for Property, CaseProperty and QuoteProperty belongs to that class hierarchy, and not Message.
This is where the DDD concept of Services would come in. The Repository for each of your concrete classes only persist that entity, not the related objects.
So you have Property(), and is the base for your CaseProperty() : Property(). This special-entity is accessed via CasePropertyService(). Within here is where you would do your JOINs and such to the related tables in order to generate your CaseProperty() special entity (which is not really Case() and Property on its own, but a combination).
OT: Due to limitation of .net of where you can't inherit multiple classes, this is my work around. DDD is meant to be a guideline to the overall understanding of your domain. I often give my DDD outline to friends, and have them try to figure out what it does/represent. If it looks clean and they figure it out, it's clean. If your friends look at it and say, "I have no idea what you are trying to persist here." then go back to the drawing board.
But, there's a catch about using any ORM to persist storage of DDD objects (linq, EntityFramework, etc). Have a look at my answer over here:
Stackoverflow: Question about Repositories and their Save methods for domain objects
The catch is all objects must have an identity in the database for ORM. So, this helps you plan your DB structure.
I have recently moved away from using ORM to control direct access, and just have a clean DDD layer. I let my repositories and services control access to the DB layer, and use Velocity to entity-cache my objects. This actually works very well for: 1) DB performance, you design however is most efficient not being coupled to your DOmain objects with direct ORM representation, and 2) your domain model becomes much cleaner with no forced identies on Value Objects and such. Free!