Is there are an easy way to store some of entitie's properties in a column as a bulk, as XML or something? Querieng by those properties of course is not an option, but it still'd be valuble to be able to extend data model without database migration.
For NHibernate you can use dynamic-component
http://nhibernate.info/doc/nh/en/index.html#components-dynamic
or
using the dictionary as a name-value list
nhforge.org/doc/nh/en/index.html#collections-mapping
or even Duck-Typing
http://fabiomaulo.blogspot.com/2009/07/duck-typing-with-nhibernate.html
As far as I know you are not able to do this directly with NHibernate, but you could implement a private property which composes and decomposes your fields to a string and map to that property instead of mapping your fields directly.
But I am not sure if this really something you should do in the first place. Usually requirements tend to come up during development and lifetime of an application and once you are going to need one of the fields - even if you now think you will never need to query for that field - you will have a hard time. Adding a column to a table of an existing database is not much of a deal and you still need to update the xml for every tuple in the table, so I really think it is better to store only one field in a column.
Best Regards,
Oliver Hanappi
Not in NHibernate. I don't know about Entity framework.
You still need a database migration to store the XML field, so it won't prevent you having to do a database schema update when you find this feature in Entity framework or some other framework.
Yes, you can do this in NHibernate using a serializable object and an IUserType implementation. This link describes how to create an IUserType implementation for a SQL Server XML field and this link describes how to build on that to serialize an object to an XML field.
You could try converting the xml to a string before you store it in the database.
The Entity Framework does not support
a native-XML data type. This means
that when an entity is mapped to a
table with an XML column, the
equivalent entity property for the XML
column is a string. Objects can be
disconnected and serialized as XML.
For more information, see Serializing
Objects (Entity Framework).
http://msdn.microsoft.com/en-us/library/cc716791.aspx
Related
we are currently evaluating whether nHibernate supports the requirements for our project. We share the database with another application so that we are not completely free as regards changes to the schema.
Some columns are filled with unique and consecutive numbers (e.g. for invoices). The next number is determined by a stored procedure that also implements a locking algorithm so that the numbers are guaranteed to be consecutive.
On the one hand we could define a trigger on the respective tables that sets the value for the column when an empty or special value is provided. This would require changing the existing database definition - though it might be the most reliable way to implement this.
In order to avoid the change of the database definition we are trying to solve this in the nHibernate ORM. We've first tried to implement a user type that calls the stored procedure in NullSafeSet if an empty value is provided. Unfortunately, the connection and transaction of the provided command are not set yet when NullSafeSet is called.
How can we solve this with nHibernate?
Thanks in advance,
Markus
If you decide to go with trigger route, then you'll need to add generated attribute to your property mapping.
Generated properties are properties which have their values generated
by the database. Typically, NHibernate applications needed to Refresh
objects which contain any properties for which the database was
generating values. Marking properties as generated, however, lets the
application delegate this responsibility to NHibernate. Essentially,
whenever NHibernate issues an SQL INSERT or UPDATE for an entity which
has defined generated properties, it immediately issues a select
afterwards to retrieve the generated values.
Aside from that, I'm not quite sure how would you call stored procedure from NHibernate issued INSERT, without adding a trigger or default constraint on column.
Edit
Looks like NHibernate has a notion of class persisters, through the interface IEntityPersister. Maybe you could hack something out from that.
The persister attribute lets you customize the persistence strategy
used for the class. You may, for example, specify your own subclass of
NHibernate.Persister.EntityPersister or you might even provide a
completely new implementation of the interface
NHibernate.Persister.IClassPersister that implements persistence via,
for example, stored procedure calls, serialization to flat files or
LDAP. See NHibernate.DomainModel.CustomPersister for a simple example
(of "persistence" to a Hashtable).
You could start from NHibernate's source.
If you have the ability to add triggers to database, that would probably be the best, straightforward way, without investing too much time to fight with NHibernate's internals.
I'm using Symfony2 and Doctrine 2.0. I'm trying to read data from an XML feed and map this to new or existing entities in the database. When data in the XML feed changes I need update existing entities, but when the data is added I should create new entities.
In my entity classes I'm using the following denormalize methods to map the XML data to the entity's properties:
function denormalize(SerializerInterface $serializer, $data, $format = null)
(Defined in Symfony\Component\Serializer\Serializer called inside my Entity classes)
The docs for this method state that "It is important to understand that the denormalize() call should denormalize recursively all child objects of the implementor." and this is what I'm trying to do. However entities should not know about the EntityManager so how do I check, inside the denormalize() method if a related/child entity already exists or not?
Kind regards,
Matthew
It is indeed a bad idea to call the EntityManager in an entity (and, as far as I know, outside a controller).
I've never faced that problem, but if I were you I'd try to denormalize in one of your controllers, or if it really bothers you, in a service that you call in a controller, and to which you give your EntityManager (here again, best do it in the controller itself, or simply send your objects to the service so it can denormalize the xml "into" the objects).
Best would be to write a controller that works no matter the entity given.
Hope that helps!
I think my problem was in my approach and not really my code!!
Originally, each time I found an entity represented in the XML I would check (using the EntityManager) to see if it was new or existing BEFORE denormalizing it. I took this route because there is duplication in the XML and I was worried about creating duplicate entities in the EntityManager. Cheacking to see if an entity already existed meant I could update the existing entity rather than create a duplicate. Now with my new approach every time I find an entity represented in the XML I denormailze it into a new entity. Of course this creates duplication in the EntityManager, just as there is in the XML, but this can be handled later, hopefully..!
So far this is proving to be a better solution, although I am experiencing some issues when trying to merge the duplicate entities in the EntityManager using $em->merge(); and cascade={"persist", "merge"}. I've posted a new question about this here: Doctrine 2.1 - Relation Lost After ManyToMany Cascade Merge - Symfony2
Matthew
In my web method, I get an object of some third party C# entity class. The entity class is nothing but the DataContract. This entity class is quite complex and has properties of various types, some properties are collections too. Of course, those linked types are also DataContracts.
I want to serialize that DataContract entity into XML as part of business logic of my web service. I cannot use DataContractSerializer directly (on the object I receive in the web method) simply because the XML schema is altogether different. So the XML generated by DataContractSerializer will not get validated against the schema.
I am not able to conclude the approach I should follow for implementation. I could think of following implementation approaches:
LINQ to XML - This looks ok but I need to create XML tree (i.e. elements or XML representation of the class instance) manually for each type of object. Since there are many entity classes and they are linked to each other, I think this is too much of work to write XML elements manually. Besides, i'll have to keep modifying the XML Tree as and when the entity class introduces some new property. Not only this, the code where I generate XML tree would look little clumsy (at least in appearance) and would be harder to maintain/change by some other developer in future; he/she will have to look at it so closely to understand how that XML is generated.
XmlSerializer - I can write my own entity classes that represent the XML structure I want. Now, I need to copy details from incoming object to the object of my own classes. So this is additional work (for .NET too when code executes!). Then I can use XmlSerializer on my object to generate XML. In this case, I'll have to create entity classes and whenever third party entity gets modified, I'll have to just add new property in my class. (with XmlElement or XmlAttibute attributes). But people recommend DataContractSerializer over this one and so I don't want to finalize this unless all aspects are clear to me.
DataContractSerializer - Again here, I'll have to write my own entity class since I have no control over the third party DataContracts. And I need to copy details from incoming object to the object of my own classes. So this is additional work. However, since DataContractSerializer does not support Xml attributes, I'll have to implement IXmlSerializable and generate required Xml in WriteXml method. DataContractSerializer is faster than XmlSerializer, but again I'll have to handle the changes (in WriteXml) if third party entity changes.
Questions:
Which approach is best in this scenario considering performance too?
Can you suggest some better approach?
Is DataContractSerializer worth considering (because it has better performance over XmlSerilaizer) when incoming entity class is subject to change?
Should LINQ be really used for serialization? Or is it really good for things other than querying?
Can XmlSerializer be preferred over LINQ in such cases? If yes, why?
I agree with #Werner Strydom's answer.
I decided to use the XmlSerializer because code becomes maintainable and it offers performance I expect. Most important is that it gives me full control over the XML structure.
This is how I solved my problem:
I created entity classes (representing various types of Xml elements) as per my requirement and passed an instance of the root class (class representing root element) through XmlSerializer.
Small use of LINQ in case of 1:M relationship:
Wherever I wanted same element (say Employee) many times under specific node (say Department) , I declared the property of type List<T>. e.g. public List<Employee> Employees in the Department class. In such cases XmlSerializer obviously added an element called Employees (which is grouping of all Employee elements) under the Department node. In such cases, I used LINQ (after XmlSerializer serialized the .NET object) to manipulate the XElement (i.e. XML) generated by XmlSerializer. Using LINQ, I simply put all Employee nodes directly under Department node and removed the Employees node.
However, I got the expected performance by combination of xmlSerializer and LINQ.
Downside is that, all classes I created had to be public when they could very well be internal!
Why not DataContractSerializer and LINQ-to-XML?
DataContractSerializer does not allow to use Xml attributes (unless I implement IXmlSerializable). See the types supported by DataContractSerializer.
LINQ-to-XML (and IXmlSerializable too) makes code clumsy while creating complex XML structure and that code would definitely make other developers scratch their heads while maintaining/changing it.
Is there any other way?
Yes. As mentioned by #Werner Strydom, you can very well generate classes using XSD.exe or tool like Xsd2Code and work directly with them if you are happy with the resulting classes.
I'll pick XmlSerializer because its the most maintainable for a custom schema (assuming you have the XSD). When you are done developing the system, test its performance in its entirety and determine whether XML serialization is causing problems. If it is, you can then replace it with something that requires more work and test it again to see if there is any gains. But if XML serialization isn't an issue, then you have maintainable code.
The time it takes to parse a small snippet of XML data may be negligible compared to communicating with the database or external systems. On systems with large memory (16GB+) you may find the GC being a bottleneck in .NET 4 and earlier (.NET 4.5 tries to solve this), especially when you work with very large data sets and streams.
Use AutoMapper to map objects created by XSD.EXE to your entities. This will allow the database design to change without impacting the web service.
One thing that is great about LINQ to XML is XSD validation. However, that impacts performance.
Another option is to utilize LINQ and Reflection to create a generic class to serialize your object to XML. A good example of this can be found at http://primecoder.blogspot.com/2010/09/how-to-serialize-objects-to-xml-using.html . I am not sure what your XML needs to look like at the end of the day, but if it is pretty basic this could do the trick. You would not need to make changes as your entity classes add/remove/change properties, and you could use this across all of your objects (and other projects if stored in a utility DLL).
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.
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.