I'm considering switching from fluent nhibernate to subsonic as nhib just seems to have a MASSIVE memory footprint which I'm really not enjoying, but I just want to check how subsonic (the simple repository probably) would cope with:
adding extra fields to a database: at the moment I can map a dictionary value to a field in the database which is VERY cool, is this possible in subsonic? (or anything similar?)
FWIW: DynamicComponent(x => x.PropertyBag, GetDynamicComponentPart); where propertybag is a Dictionary.
many to many relationships
cascading saves/deletes
mapping a complex object to an xml or varchar(max) column (seralize it to xml obviously)
* adding extra fields to a database: at the moment I can map a
dictionary value to a field in the
database which is VERY cool, is this
possible in subsonic? (or anything
similar?)
FWIW: DynamicComponent(x => x.PropertyBag,
GetDynamicComponentPart); where
propertybag is a Dictionary.
Adding fields is fairly simple. Just add the field to the table, then re-generate the classes from the T4 template.
You won't get any mapping beyond basic primitive types, though. Certainly not a dictionary in a field.
* many to many relationships
You will have to make custom modifications to the T4 template to get any sort of support for many-to-many tables. SubSonic just treats them like any other table.
I have made such modifications and they are of limited usefulness.
* cascading saves/deletes
Only on the RDBMS side. That is, if you setup foreign key relationships with cascades. SubSonic doesn't do any of this.
* mapping a complex object to an xml or varchar(max) column (seralize
it to xml obviously)
Nope. You get no support like this. There are no extensibility hooks to insert your own type converters.
SubSonic is a completely different field from NHibernate. I would call NHib an ORM, but I would not call SubSonic that. Rob Conery, the author of SubSonic, would call it a query tool.
It is very simplistic, which is its goal and strength (as well as weakness). It assists with querying and modifications in a strongly typed way. It lacks a huge amount of features and configurability/extensibility compared to NHib or even Entity Framework.
I would caution against moving from NHib to SS, especially if you have any amount of functionality implemented in NHibernate already. Not that SS is a bad tool, but it has a lot of restrictions.
Related
We are using Lucene as the search server for data retrieval.
With this come certain complexities that I was unprepared for, not the least of which is managing relationships between objects.
I want to create a clean and simple POCO for our domain objects. These POCOs will contain related objects that I need for the UI, but no other fields (IDs defining these relationships, various other fields I simply don't need on the UI)
This means that I cannot directly translate Lucene's Hits collection into my UI-friendly POCOs and need some intermediary set of classes that will, at the least, contain IDs of related objects (stored in the same, or other indeces). I hesitate to call these DTO objects but for the sake simplicity I will call them that.
So I envision it working as follows:
Perform query in Lucene -> Hits collection
Iterate through Hits -> DTO collection
DTO collection -> [service to retrieve related objects, compose a POCO] ->
POCOs
Render a UI using the shiny simple POCOs
My fear in doing so is that I'll end up with Anemic Domain Model ( http://www.martinfowler.com/bliki/AnemicDomainModel.html ).
Is this a valid concern or am I on the right path?
I've ended up going the familiar to me pattern of a DTO. DTO has all the IDs - it is merely a CLR reflection of a record retrieved from Lucene.
I then map from DTO to a POCO in the service layer and use those objects to render the UI elements.
Does not feel slick, but it works.
Without any ID information in your POCOs, your design will likely suffer from anemia as there will just be an unconnected jumble of objects (which may not even fit all in memory at once). Also, it would seem to me that the lack of IDs would greatly interfere with caching and memoization (which help in not hitting the database every time you need an object). I have rarely had the luxury of assuming that all of my data will fit in memory all at once.
I have a class structure which is akin to a PurchaseOrder (parent) and PurchaseOrderLine (child) pattern, where the order lines will only be saved to the DB by saving the parent PurchaseOrder and will only ever be accessed via the parent too.
The DB has PurchaseOrderLine.PurchaseOrder set to not permit null values.
It seems from searching through the web that it is not possible to have a uni-directional association from PurchaseOrder via an IList property without having to have a property on the line pointing back when the child has a NOT NULL constraint for its PurchaseOrder column.
Is this really the case? It seems like one of the most basic things one would want to do with an ORM, I find it difficult to accept that a product as mature as NHibernate cannot handle such a basic scenario.
No it's not the case. Please see the example provided in the answer to this question: When to use inverse=false on NHibernate / Hibernate OneToMany relationships?
Well, it may be the case that you can't have unidirectional one-to-many relationship defined only on one side, but I'll argue with your statement that this is "one of the most basic things one would want to do with an ORM".
One of the most basic things would be to have unidirectional one-to-many defined only on many side - as it is natural for RDBM tables. And ORMs (despite the common misconception) are not intended (or able) to fully abstract domain model from underlying data source. Even if in some cases they can, the database side suffers from select N+1 problems or very ineffective queries.
Defining one-to-many at one side makes an impression that i.e. counting the collection is cheap. It is the case with plain object graphs, but not with NHibernate entities, as reading collection causes (at least one) call to the database. Eager fetching from one side is also not able to properly use database join mechanism in the way it's intended to be used (opposite to eager fetch from many side).
Even if I don't agree with a lot of arguments, I think it is useful to read some of the articles saying that "ORM is an anti-pattern", like this one. They helped me to leverage the way I think about ORMs and make me think about ORMs as a compromise between two not matching paradigms, but not the way to hide one behind another.
This can now be achieved in NH3 using the Not.KeyNullable()
this.HasMany(x => x.Actions)
.Access.BackingField()
.KeyColumn("[Application]")
.Not.KeyNullable()
.Cascade.AllDeleteOrphan();
I have a complex, 3NF database being provided to me for a particular project. I would like to avoid using a class-per-table domain design. Rather, I would like to model my domain objects after how they are used from a conceptual business perspective.
The rub is how to properly persist this information. I know I can go the ADO route, but I'd like to take a stab at using NHibernate, having used it successfully on other projects with more flexible data stores.
So, I need to know if NHibernate will support the following scenario:
I have a conceptual object known as a ProjectStatus, which is comprised of a handful of date stamps for various activities along with some notes about the status. All of the data that comprises the ProjectStatus comes from 2 or more tables. There is no ProjectStatus table.
I know I can do a union-subclass in my NH mapping to get this to work, but...
One of the tables that holds the bulk of the information I need has a composite id (two PK fields that together make up the identity signature). I know NH supports composite ids as well, but how would I go about mapping my the union on the composite key? Do I need to specify a composite key underneath the union-subclass section?
The dba has refused to budge on her near-neurotic 3NF data model, so I'm stuck on that front. If I have to drop to ADO for ease/speed of development, so be it, but I'm hoping NH will rise above...
I gather that you have a base-class and two sub-classes that you want to map to two sub-class tables using the table-per-concrete-class mapping strategy. The two sub-class tables need to declare the same primary keys, and the primary keys need to be mapped in the base-class mapping. You have to declare the id or composite-id in the base-class mapping, so that you can ask NHibernate for an object of the base-class type with the given ID or composite ID. You can't declare them in the subclass-mapping, and you certainly can't declare them to be different for each subclass type (that's what declaring them in the subclass mapping would permit you to do), because from a strongly*-typed object-oriented perspective, that would be leaving the realm of sanity.
*Strong typing, to me, means that variables are statically typed (the type of each variable is known to and enforced by the compiler) and objects are strictly typed (the type of each object is known to and enforced by the runtime).
Is there an easy way to automatically truncate strings using fluent nHibernate mappings. I would prefer to not address this the setters or a custom type, but with something in the mapping files.
If I understand you correctly you want to make sure strings persisted to the database are no longer than a specified length. This sounds like it could be a business concern though and probably does belong in the domain model or as validation logic.
This question appears to have been asked before and the solution was a custom nHibernate UserType. Keep in mind this isn't a custom entity type or base class, this is a custom mapping type that nHibernate can understand.
Automatically truncating strings in NHibernate / SQL Server
If the custom usertype solution isn't to your liking then you could implement a custom interceptor, but I don't believe there is anything in nHibernate that does this "out-of-the-box". However, that is the beauty of nHibernate is that it is very extensible and implementing a custom user type for your situation is not difficult at all.
The terms are often thrown around interchangeably, and there's clearly considerable overlap, but just as often it seems implied that people see something strongly implied by saying that a system is an ORM that isn't implied by it being a DAL. What is that? What, if any, are the key points that differentiate these types of system?
For example, let's say I have some code that implements Database, Table, Column and Row classes, populating them by automatic analysis of an existing database, allowing simplified interaction and so on. It understands, enforces, and takes advantage of structural relationships between database entities, such as foreign keys. All the entity models can be subclassed to load table-specific functionality onto them.
To what extent is this a DAL? To what extent is it an ORM? Why?
ORM = Object-Relational Mapping
In an ORM, classes/objects in the application are mapped to database tables and operations for persistence, sometimes automagically.
DAL = Data-Access Layer
In a DAL, database operations are hidden behind a code facade.
An ORM is a kind of DAL, but not all DALs are ORMs.
I think an ORM is capable of mapping any set of objects to a relational database; whereas a DAL is specific to your application, and probably couldn't naturally be extended to support other objects.
Not only that, but a ORM specifically is concerned with mapping classes to/from the database entities, while a DAL may simply be a way for you to access the data in a database, without any mapping.
Any object orientated DAL connecting to any storage system that is not saving objects implements an ORM. ORM is generally understood to mean something like Hibernate, but the important thing is the handling of impedance mismatches.
[Expanded]
At a data level, an impedance mismatches occur when you are mapping data of one type (relational) into data of another (OO).
For instance, how many times have you seen a line like below in your DAL?
db.AddInParameter(dbCommand, "Name", DbType.String, name);
Or the other side
customerId = Convert.ToInt64(dr["CustomerID"].ToString());
Many issues come up when mapping your primitive data types.
At a object level, your DAL should be returning the structures you intend to use. Be it some sort of business object or just a bunch of raw data. Both your own DAL and the ORM need to handle this.
At a design level, the objects you construct are reflective of your stored data. So a structural difference can occur. These are also handled for you within ORM solutions, but you would be forced to do the same within a DAL. For example, within your OO code it would be nice to implement proper inheritance, but that does not covert easily into something relational.
I just wanted to point out that ORM is a term coined to push products that automate a lot of what you would already have to do within your DAL. The ORM solutions will make life easier and provide a large number of quality/performance benefits. But that doesn't change the fact that one of the major components of your DAL is creating your own ORM.
ORM didn't exist when I started programming. When the first ORMs came out, they were external tools used to create the DAL. Now days, DAL and ORM have intermingled. That's why a lot of developers use the terms interchangeably.
The most well known example of an ORM that functions as a DAL is NHibernate. Other examples are Subsonic and CSLA.NET. These are all .NET tools. IIRC, ORM tools started in the Java world. Other technologies stacks then copied what Java has done.