- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Need global search & replace for tables and columns
Joined: 10-May-2007
We are developing a new application that is a copy of a previous application, with various changes to entity names and terminology. A great many tables and columns have been renamed.
Scripting the old database and doing global search and replace has worked very well for creating the new database. Unfortunately, the LLBLGen project seems to be rather difficult to deal with, since it is stored as a binary file rather than as text/XML.
Is there any way to do a global search and replace on an LLBLGen project to rename entities and typelists, etc.? There are literally hundreds of changed tables/columns. It would take forever doing it by hand in LLBLGen Pro.
I see there is a "Template Studio" available for download. Does this tool provide what I need?
Thanks for your help.
Jeff
I see there is a "Template Studio" available for download. Does this tool provide what I need?
The template studio is about changing the code generation templates.
I think in your situation, the best thing to do is re-fresh the catalog pointing to the new database. Or even create a new Project.
Indeed, using a copy of the .lgp file and refresh it on the new catalog would be best. To point the .lgp project to a new catalog, go to the catalog explorer, rename the catalog to the catalog (presuming you're on sqlserver) you want to work with in this project, and do a refresh.
Joined: 10-May-2007
Thank you for the suggestions.
I successfully changed and refreshed the catalog, but unfortunately there were a large number of tables that were re-mapped incorrectly (to the wrong table names).
It did manage to re-map some of the table names correctly, which is rather impressive because the new table names bore very little resemblence to the old ones. For the correctly re-mapped tables, LLBLGen did a great job of re-mapping the renamed columns.
However, there are still hundreds of manual changes I will have to make if I can't find an easier way to re-map (it is quite a large project with lots of TypeLists).
Is there any type of project import/export utility to/from XML? If only I could run a global search and replace... it would save me days of tedious, error-prone work.
Thanks again for your help.
Joined: 10-May-2007
I decided to stop whining and just rename all the entities and TypeLists manually. Then I refreshed the catalog hoping that the fields and relations in the entities and TypeLists would be re-mapped as well.
The generation/re-mapping seemed to go much better -- the generation output showed that most of the tables were re-mapped successfully, and also showed that most of the renamed columns were correctly re-mapped as well.
The problem is...
...when I expand the entities to look at the mapped fields and relations, they still show the old names. In the editor, the Target values correctly show the new column names, but the Field Name values are still the old names.
Ugh. What can I do?
Also, I can't seem to figure out how to change which table an entity is mapped to. (some entities were incorrectly re-mapped) In the Entities List I can easily see which ones need to be changed, but there's apparently no way to do it. In fact, I can't seem to manually re-map anything (tables or columns). (I'm new to LLBLGen, as you've probably already guessed)
A setting in the Preferences allows syncing with table names/field names after a refresh. You should set that to true, then refresh again. Setting is SyncMappedElementNamesAfterRefresh.
You can't remap an entity from _tableX _to tableY. You can switch on manually map renamed targets after a refresh: ManuallySelectRenamedtargetsAfterRefresh preference should be true. You should set it to true, load the OLD project and refresh. If you refresh on your new project, there won't be any changes.
For more info, please read: LLBLGenPro Help - Using the designer - Refreshing the catalog schemas
Joined: 10-May-2007
Thank you, daelmo. Your advice has gotten me 75% of what I need.
I opened a copy of the original project, set the ManuallySelectRenamedTargetsAfterRefresh and SyncMappedElementNamesAfterRefresh settings to true, and refreshed the catalog.
After manually re-mapping the entities, all entities, fields, indexes, etc. are looking great.
The only thing that remains now is that all of the TypeLists still have the old names in their Field Alias and Caption values. I looked around for a preferences setting for this, but did not see anything. I guess this is as far as the automated options will take me, and I'll have to manually update all of the Field Alias and Caption values. Oh well. Thank you for saving me a lot of time, though. At least the Entity Field Name values are accurate, and that makes it easier to manually update the Aliases.
If I could put a feature on the wishlist, it would be a right-click option on a TypeList's "Fields mapped on entity fields" node that provides an option for "Set Field Aliases to Entity Field Name values". When this option is selected, a dialog would be displayed that has a checkbox for "Update captions".
I have about 45 TypeLists, each with a fairly large number of fields, to manually update. So I guess I'd better get busy.
Thanks again.
It might be an idea to write a plugin using the code provided in the SDK for renaming the typedlist fields. This way it might take you an hour or so and it will be less boring
Joined: 10-May-2007
Well, I may just have to write a plug-in after all. The issues are deeper than I thought.
Now I've realized that all the relations still have their old names too, which is causing all kinds of problems with the generated DAL. To work around this, I would have to manually rename all the relations in all the entities.
Goodness gracious, is there any way to get an LLBLGen project exported to an XML file? Otis: If you could give me a quote for how much you would charge to write an XML import/export utility for project files, I'll run it by my manager.
Joined: 10-May-2007
Just to clarify... the relations themselves were successfully re-mapped... it's the "Fields mapped on related fields" for the entities that still use the old names.
SpectacleOne wrote:
Well, I may just have to write a plug-in after all. The issues are deeper than I thought.
Now I've realized that all the relations still have their old names too, which is causing all kinds of problems with the generated DAL. To work around this, I would have to manually rename all the relations in all the entities.
Goodness gracious, is there any way to get an LLBLGen project exported to an XML file? Otis: If you could give me a quote for how much you would charge to write an XML import/export utility for project files, I'll run it by my manager.
First: exporting it to XML is a big pain, as the references of the objects are a multi directional cyclic graph, not a tree unfortunately. Trees are easy to export to XML, but a cyclic graph isn't as you then have to emit 'reference' elements in the XML which effectively make it useless for manually editing (think SOAP XML serialization output). We will do a second attempt to get this sorted out with a textual DSL in the fall of 2007 (export to 3 files, import them again).
What I wonder though is why you run into this trouble as the refresher should take care of a lot of these things. Did you use a wrongly refreshed .lpg perhaps as a starting point? (as there was some confusion in the earlier parts of this thread which might have made you pick a .lgp file to start with after a refresh which already made a lot of tables mapped wrong)
Also, I'm a bit confused what the context is of your project. Am I correct that you have already written code for DB X and you now want to re-use that code for DB Y though it requires completely differnet mappings?
Fields mapped onto related fields are called 'Forf's in the object graph. What do you mean exactly with 'have the wrong names' ? Could you elaborate on that a bit please so I can give you hints how to solve this properly and easily?
Also, if you could give me the exact state of where you are now and what you want to achieve, I know what we're talking about so I can give you more precise hints or write a small plugin for you which could help you out. For example, writing a plugin which resyncs the names of the Fields mapped onto related fields is 30 minutes work for me, tops. Though I have to know what exactly you want to have and how the names are now. This is because a field mapped onto a related field actually refers to a real field object.
Joined: 10-May-2007
Hi Otis,
Thank you very much for taking the time to look into my situation and provide such a detailed response.
I spent about 3 hours yesterday manually renaming all "Fields mapped on relations" (Forf's) for all entities and I finally have everything generating fine and things look good. So, I no longer have an immediate need for assistance.
However, I will explain exactly what I was trying to do, and how I accomplished it. It may help others, and may inspire new features for future versions of LLBLGen:
We are creating a software product that will begin as a copy of a previously developed product. (We are successfully using LLBLGen for our original project.)
The new product uses almost all the same tables as the old product, but a great many of the table and column names have been renamed to suit the new product.
I scripted the old database (SQL Server 2005) and ran global Search and Replace commands to rename the tables, columns, indexes - including primary keys and foreign keys, stored procedures... etc. This worked very well. The new database is exactly what we want.
The next idea was to copy the original LLBLGen project and perform the same renaming operation. This could not be done on the project file directly because it is a binary file. And since LLBLGen Pro provides no means to run a global Search and Replace on all named objects, I was stuck.
After receiving valuable advice from Daelmo (in this thread), I opened a copy of the original project file and made the following changes in Preferences: ...... ManuallySelectRenamedTargetsAfterRefresh = True ...... SyncMappedElementNamesAfterRefresh = True
During catalog refresh, these settings allowed me to directly specify the new table names, and also ensured that the entity field names and the typed list aliases were properly refreshed to the new names.
One problem remained, however, and that involved the "Fields mapped on relations" (Forf's) for each entity. The actual mapped fields were correct, but the name of each Forf still contained references to old table names.
For example: Let's pretend that the original project has a Forf named CustomerCollectionViaSupplier. The Customer and Supplier tables in the old database were renamed to Client and Vendor in the new database. After refreshing the catalog and manually re-mapping the renamed tables, the Forf is correctly re-mapped, but instead of the Forf being named ClientCollectionViaVendor, the name is still CustomerCollectionViaSupplier. This is causing collection classes to be generated with the wrong names.
The only way I could find to correct this situation was to manually step through each Forf and rename it. (a rather long and error-prone task for a large database) All is well now, but it seems there should be a better way to handle this.
If there was a way to right-click on the Forf collection and choose "Refresh Forf names from mapped tables" (or something), that would be fantastic. In my situation, it would be even better to have this capability at the entity collection level. That way, all entitiy Forf's could be refreshed at once. Of course, this is a potentially dangerous feature, but for those of us who only use the generated names anyway, it would really help in these situations.
(By the way, I also ran a global Search and Replace on our application code base, and everything is compiling and running using the newly generated LLBLGen data access layer.)
Thank you again, Otis. I hope my description has helped clarify what I've been trying to accomplish.
I'm sure I will be renaming more tables and columns. So if you are able to put together a ForfName-refresh plug-in, I will definitely put it to very good use.
I look forward to your Fall 2007 effort to provide a 3-file textual DSL import/export feature. This will help many of us... whether it's a need for global search and replace, or a need for textual representation for better source control versioning history.
Jeff
SpectacleOne wrote:
Hi Otis,
Thank you very much for taking the time to look into my situation and provide such a detailed response.
I spent about 3 hours yesterday manually renaming all "Fields mapped on relations" (Forf's) for all entities and I finally have everything generating fine and things look good. So, I no longer have an immediate need for assistance.
Glad it's sorted, although not as smooth as you'd hoped.
However, I will explain exactly what I was trying to do, and how I accomplished it. It may help others, and may inspire new features for future versions of LLBLGen:
We are creating a software product that will begin as a copy of a previously developed product. (We are successfully using LLBLGen for our original project.)
The new product uses almost all the same tables as the old product, but a great many of the table and column names have been renamed to suit the new product.
Ok, so the tables and columns are, structure-wise, the same but have different names.
I scripted the old database (SQL Server 2005) and ran global Search and Replace commands to rename the tables, columns, indexes - including primary keys and foreign keys, stored procedures... etc. This worked very well. The new database is exactly what we want.
The next idea was to copy the original LLBLGen project and perform the same renaming operation. This could not be done on the project file directly because it is a binary file. And since LLBLGen Pro provides no means to run a global Search and Replace on all named objects, I was stuck.
After receiving valuable advice from Daelmo (in this thread), I opened a copy of the original project file and made the following changes in Preferences: ...... ManuallySelectRenamedTargetsAfterRefresh = True ...... SyncMappedElementNamesAfterRefresh = True
During catalog refresh, these settings allowed me to directly specify the new table names, and also ensured that the entity field names and the typed list aliases were properly refreshed to the new names.
That indeed should have fixed alot of trouble.
One problem remained, however, and that involved the "Fields mapped on relations" (Forf's) for each entity. The actual mapped fields were correct, but the name of each Forf still contained references to old table names.
Oh! no, I'm sorry, this is a confusion. Field mapped onto relation: is called internally 'UtilizingPropertyName'. Load a project in the designer, rightclick the project node in project explorer -> run plugin -> Project inspector. Now browse to the entities node in the project inspector tree (which shows the object graph of the project), and browse to an entity's relations, click a relation and you'll see 'UtilizingPropertyName' at the right.
Field mapped onto Related Field is called a forf internally or if the name wasn't too long. I now figure you had a struggle with the field names of the fields mapped onto relaties, I thought you had problems with forfs.
Next time, what you could have done was this: - a simple plugin which runs over all entities and all relations in these entities and then calls for each EntityRelation object for an entity E the routine E.CreateUniqueUtilizingPropertyName(relation, project.Properties);
This gives back a string which is the new utilizing property name for the relation passed in and which is guaranteed to be unique for the entity the method is called on.
So in short:
// plugin execute routine
public override void Execute()
{
Project p = base.ProjectToTarget;
foreach(EntityDefinition e in p.Entities)
{
foreach(EntityRelation r in e.Relations)
{
r.UtilizingPropertyName = e.CreateUniqueUtilizingPropertyName(r, p.Properties);
}
}
}
(not tested, but it should give an idea).
The advantage of an object model over text is clear here, but I fully admit, getting to the object model can be a bit challenging.
Another way to update objects in the project model is via a program, for example by using the C# code of the command line catalog refresher as a starting point: use the project load/save code that's there and for the rest use the code above to do what you want.
For example: Let's pretend that the original project has a Forf named CustomerCollectionViaSupplier. The Customer and Supplier tables in the old database were renamed to Client and Vendor in the new database. After refreshing the catalog and manually re-mapping the renamed tables, the Forf is correctly re-mapped, but instead of the Forf being named ClientCollectionViaVendor, the name is still CustomerCollectionViaSupplier. This is causing collection classes to be generated with the wrong names.
The only way I could find to correct this situation was to manually step through each Forf and rename it. (a rather long and error-prone task for a large database) All is well now, but it seems there should be a better way to handle this.
I agree. It's not a common task though, but it should have been more smooth. I'm sorry I didn't have a more clearer picture earlier on, as I then would have given you the routine above and you would be able to have renamed everything in half an our, tops.
If there was a way to right-click on the Forf collection and choose "Refresh Forf names from mapped tables" (or something), that would be fantastic. In my situation, it would be even better to have this capability at the entity collection level. That way, all entitiy Forf's could be refreshed at once. Of course, this is a potentially dangerous feature, but for those of us who only use the generated names anyway, it would really help in these situations.
(By the way, I also ran a global Search and Replace on our application code base, and everything is compiling and running using the newly generated LLBLGen data access layer.)
Thank you again, Otis. I hope my description has helped clarify what I've been trying to accomplish.
It now does indeed .
I'm sure I will be renaming more tables and columns. So if you are able to put together a ForfName-refresh plug-in, I will definitely put it to very good use.
The routine above does a refresh of all relations in all entities. If you start with the Custom property plugin sourcecode, you'll see that there it has code to check which entities are selected, so you can then use that list to traverse. Getting it up and running shouldn't take a long time. You can also use the command line route if you feel more comfortable with that. THe full project object model is documented in the sdk reference manual.
I look forward to your Fall 2007 effort to provide a 3-file textual DSL import/export feature. This will help many of us... whether it's a need for global search and replace, or a need for textual representation for better source control versioning history. Jeff
We did try to make a project merger routine, and we got pretty far but it is a complex problem to solve. As a lot of object reference each other, it can be a challenge when to update what without breaking anything. Merging changes isn't that hard unless dependencies come into play and of course you really want to solve things correctly so if you first think 'a typed list will break because of this, so we won't allow it' but afterwards you see that the typedlist was changed as well, it might have been a no-brainer.
So that project was put on hold as I couldn't solve a couple of major problems with it. Instead we're looking into moving into a different direction: creating a dsl for the mappings and allow imput/output of mapping files in that dsl format. So the schema info and the mapping info and the entity info (3 files) are then exported, you can then merge if you want, and then imported again for v2.x, and for v3 we might move altogether to that format.
A DSL (text-based dsl) is then also an option for people who want to create mappings by hand.