Now it’s time to face with a real project and how it works with CodeFluent Entities. My experiences concerns a project with around 50 entities, so it is not so big, but enough to collect issues and think what could be done better before next, maybe bigger, project.
Version Control System
The goal was to keep sources ready to compile and run for everyone also for those who doesn’t know anything about CodeFluent Entites. That indicated keeping everything what CodeFluent generates in version control system.
First was Microsoft Visual Source Safe 2005 (I know that is old tool, but it was not my decision to use it). There were few problems with that:
- CodeFluent recreates every generated already file from the model. That means every file is changed. However producers don’t checkout files. The developer need to do it by himself and find manually what had changed and commit it to source control.
- CodeFluent adds time stamp to (almost) every generated file. That indicates conflicts problems when 2 developers run producers independently.
- There is also .NET runtime version added which can be different depending on windows version, service packs you have installed and finishing on language packages installed on the system
I think the first problem was the biggest we face in this matter, because the developer could not catch every changed file and commits could not be compiling. To avoid this situation every developer had to regenerate model after they got latest version. So the goal was not achieved.
The solution was to move sources into other version control system: Git. The main reason was that Git is comparing files by their content, so the files are checked-out when the content was different than in the last commit. Yes, but time stamps are different every time we generate model. This option can be turned off in CodeFluent configuration file (defaultProducerProductionFlags=”RemoveDates”). What about .NET runtime version? We use simple patch producer (also from the CodeFluent package), that simple removed runtime version (using regex) from every file at the end of generating. (EDIT: Since 1 March 2013 Codefluent Entities (build 702) provides RemoveDiffs production flag that is also removing the Runtime Version from generated files. Now patch producer is redundant)
Own tracking properties
Our other goal was to use our own login system and keep entity tracking who changed entity and when. CodeFluent provides standard mechanism to track changes, but there is no possibility to change the user name. This name is in format “ComputerName\WindowsLoggedInUser”. The solution was CodeFluent aspect functionality. The aspect can in very simple way manipulate whole project (entities, their properties, methods, etc). For example we can add some properties to all entities. On the build such aspect will be executed before producing. That is how we add additional properties to (almost) all entities. The other problem was to find the place where the properties would be filled in with data (user name) from application global context.
First try was OnBeforeSave rule. It was working fine when you always save objects using Save() method. OnBeforeSave is not executing always, especially when you try to save modified collection of objects. As we use WCF architecture we knew that each object that we need to save is serialized. That is why we use OnSerializing rule to fill in all data. This works fine also for collections.
Minimize transferred data
Next goal was to minimize transferred data. It is very important on loading a collection of data, because when entity is connected with other entities, than it is most likely they will be also loaded with collection. The problem is that this is done one by one, not as a whole (single query). This is very inefficient, especially when the collection is big. The good solution was to use views functionality. We can simply define a view that contains only data we need on the list and it takes only one SQL query. The view can be done very simple. You can just say which properties from the entity and connected entities you need. There is also possible to create own view query (so called “raw view”), where we can use any SQL query.
Note that this approach is good only if you not editing whole collection in-line (i.e. in grid).
For the developer it is good to edit xml data as fast as needed, however this is difficult due to CodeFluent XML-Synchronizer that is checking integration between all XML parts. It is still not perfect, so it may cause problems when project is loaded in Visual Studio. As Softluent support says on their forum “Modifying a .CFP part file when the project is loaded is not the recommended way of changing the model“. For the developer that is an issue, because the synchronizer may change your XML files and you even don’t see the difference on the editor, until you build the model or reopen Visual Studio. For example there is modelNullable attribute for viewProperty node. It can just disappear when saving some XML part. Also it is very possible that synchronizer will compress complex SQL queries into one line of code! I don’t think I need to write how this can be painful when you need to edit it.
What I wrote is not all issues we had in real project. Those ones were most time consuming to solve them. I bet you will also find some issues during your development. CodeFluent Entities is not perfect. Personally I submitted at least 5 bugs. However they have very good support and they solves bugs very quickly. They are also ready to help and give you some workaround if possible. Finally I can recommend CodeFluent Entities for software development. Despite of all issues we had, it really can simplify life during development.
- It is good idea to use Git as version control system
- To avoid conflicts and time spent on resolving them, it is better to turn off adding dates to generated files
For the same reason it is good to remove also runtime version (i.e. by using Patch producer) (redundant since 1.03.2013 – see edit note above)
- Use aspect to automatically create properties, methods, etc. in all entities
- Use views when possible to minimize transferred data
- XML-synchronizer is not perfect, so it is not recommended to edit XML parts when project is loaded.
If you have some comments, please leave it below. Thanks.