Joined: 30-May-2019
Trying to understand how LLBLGen Pro works and if it is a replacement for my current ORM, I have a few questions:
- I have a VB.NET project compiled for .net 4.7.1 x86 (running on x64 machine), I have created Enums.typeimports and placed it in the project file folder <typeImports> <typeImport typeName="Trackem.Base.Data.Model.AudioFile.Categories" assemblyFile="d:\Develop\Trackem5\Libraries\Base\bin\x86\Debug\Trackem.Base.dll"/> </typeImports>
When I open the x64 designer I get an error that the file needs to be compiled for .net 4 which I assume is meant to say I am trying to load a x86 dll in a x64 app. So I moved to the x86 designer. In the x86 designer I get no error in the app output but the type is not loaded (I really think there should be some UI for this instead of me having to edit xml files).
- I will probably be using the adapter approach. Since I am currently using the discontinued Telerik Data Access ORM, I already have the ORM classes and data access code all within one project. Is there a way to make the generated code all be put into one project (and on the way skip the project file generation as I do have other code in the project as well). I want the designer to only generate the class files and to put them in the folders I specify
Thanks
Joined: 30-May-2019
I think I found a bug that caused this: If I reference an enum that is just coded as a stand alone in the namespace it all works fine. however if I try to reference an enum that is nested inside a class the type is not imported
in the path Trackem.Base.Data.Model.AudioFile.Categories, AudioFile is actually a class in the Trackem.Base.Data.Model namespace and is not imported whereas in Trackem.Base.Data.Model.RecurrenceRule.RecurrenceDay, RecurrenceDay is an enum in the Trackem.Base.Data.Model.RecurrenceRule namespace which did work
The question that comes to mind is why do I have to go through all this trouble of importing these enums. In the Telerik Data Access ORM which I am comparing to, I could just write in the type field what I wanted. this compiles to code anyway so any invalid type I write will just not compile
Also, please answer my other question of making the two folders of DatabaseGeneric and DatabaseSpecific into one folder under my own project (I just want output of the class files needed for the ORM). How can I do this?
Joined: 17-Aug-2003
DaniAvni wrote:
I think I found a bug that caused this: If I reference an enum that is just coded as a stand alone in the namespace it all works fine. however if I try to reference an enum that is nested inside a class the type is not imported
in the path Trackem.Base.Data.Model.AudioFile.Categories, AudioFile is actually a class in the Trackem.Base.Data.Model namespace and is not imported whereas in Trackem.Base.Data.Model.RecurrenceRule.RecurrenceDay, RecurrenceDay is an enum in the Trackem.Base.Data.Model.RecurrenceRule namespace which did work
The question that comes to mind is why do I have to go through all this trouble of importing these enums. In the Telerik Data Access ORM which I am comparing to, I could just write in the type field what I wanted. this compiles to code anyway so any invalid type I write will just not compile
A nested type has to be specified with a '+' sign, like this:
<typeImport typeName="EnumTypes.ClassWithInner+InnerEnum" assemblyFile="\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\UnitTests\LLBLGen Pro\EnumTypes\bin\Debug\EnumTypes.dll"/>
The reason you need to import the actual types and not just type whatever name they have is that we can do analysis on them and validate that things actually work at runtime. If you type in some type that you think is the name of the type, but you made a typo, you will face problems at runtime and then you're wondering why the designer didn't warn you about that. With the real types we can.
Nested enums are a bit of a struggle, granted. The reason you have to specify the nested one with a + is that the name specified is the name of the type we pass to Type.GetType() so we can instantiate it. .NET requires the '+' sign for nested types.
Also, please answer my other question of making the two folders of DatabaseGeneric and DatabaseSpecific into one folder under my own project (I just want output of the class files needed for the ORM). How can I do this?
It's not recommended to do this, as the projects serve a different purpose: the database generic one is the one with the entity classes and doesn't contain any persistence logic. The DatabaseSpecific one does. Cramming these together into 1 vs project is what most ORMs out there do but it's less flexible.
Keep in mind we're not a drop in replacement for telerik's ORM. So migrating to our ORM will require some changes in your own code / project.
That said, if you want to, you can. Open project settings, go to 'LLBLGen Pro Runtime Framework' then clear the Adapter db generic sub folder name setting and the Adapter db specific sub folder name setting.
This still generates a csproj for the dbspecific project. If you want to get rid of that, you have to remove a line from the preset. Open preset viewer in designer, select the adapter generic preset you want to use, select 'copy as new...', give it a unique name and select a folder to save it in. The folders available are the ones the designer will look for additional files. If you want to specify another folder, specify it as an 'additional tasks folder' in the project settings under 'general'.
Once the copy has been created, scroll down to: "<taskPreset name="SD.Tasks.Adapter.VsNetDbSpecificProjectFileCreator" requiresCleanCache="false">" and remove the xml element and its children, so this complete block:
<taskPreset name="SD.Tasks.Adapter.VsNetDbSpecificProjectFileCreator" requiresCleanCache="false">
<parameters>
<parameter name="cacheFilenameWithID" value="2" />
<parameter name="filenameFormat" value="[projectName][dbspecificSuffix].[extension]proj" />
<parameter name="templateID" value="SD_VsNetDBSpecificAdapterTemplate" />
</parameters>
</taskPreset>
This will then not create a csproj for the dbspecific files. If you don't use the new csproj format you have to add them to your project manually. From then on use this preset to generate code.
Joined: 30-May-2019
Hi Frans,
Many thanks for the answer. The enum was successfully imported but I think there should be UI for that instead of having me work directly on the import file. especially if there is special syntax to use for different cases of where the enum is in.
as for joining the projects into one, what flexibility am I loosing? The only flexibility I can think of is supporting multiple databases. am I missing something else as well?
Joined: 17-Aug-2003
DaniAvni wrote:
Hi Frans,
Many thanks for the answer. The enum was successfully imported but I think there should be UI for that instead of having me work directly on the import file. especially if there is special syntax to use for different cases of where the enum is in.
True, we could add an importer and generate the file from that. The main issue is that we want the import information outside the project file as it might be the dll is at a different location on a different system the project file is used. A different import file would solve that, having the information in the project file would break in that situation. So we always have to generate that import file in that situation.
We'll think about it.
as for joining the projects into one, what flexibility am I loosing? The only flexibility I can think of is supporting multiple databases. am I missing something else as well?
The main advantage you're losing is that you can separate the concern of 'database access/persistence logic' from the logic which works with entities. E.g. if you have classes working with the entity classes, that assembly always has the ability to persist them too. For some that's not a big problem, for others it is. I don't know your project situation, but some teams don't want some developers to have direct access to persistence logic in their code as all persistence logic is performed by e.g. a service.
The follow up question you might want to ask is why isn't this optional, well, things change along the way so having this as optional for Adapter would mean that half-way a project changing this setting would break everything, hence we haven't made this as optional: it's a design aspect you have to work with from the start. We haven't heard that this is a problem since it was introduced back in 2004, but I understand that if you come from e.g. EF or telerik's orm that things are a little odd at first.
Joined: 30-May-2019
I do not mind the extra file for the enum references but if that saves relative paths, I can embed the llblgenproj file in git on the root of my solution, then for every developer of the project the binary holding the enum would be in the same place.
Also, I would love some insights on best practices for a team to work with the project using git. I assume the llblgenproj is commited to git. what we have been doing is that for every branch that needs DB changes we create a two db copies of the master project DB (one for the branch and one as a common base), then we make all changes on the branch DB, and when the feature is complete we can use the common base, the branch DB and the master project DB and do a three way merge of the them into the master project DB (same idea as git handles conflicts). this works out great for us but I was wondering how should a developer change the llblgenproj file so that it references the branch DB and not the master project DB? Am I correct to assume that the changes needed are in <Catalog Name="LBS_1135v6"> under catalogs and TargetName="LBS_1135v6:dbo:AudioFiles" in an EntityMapping where in this case LBS_1135v6 is the name of a branch DB
Joined: 17-Aug-2003
Accessing the branch DB at runtime? You can use catalog / schema name overwriting at runtime, please see: https://www.llblgen.com/Documentation/5.5/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_applicationconfiguration.htm#catalog-name-overwriting-sql-server-mysql
You can do this per call as well, in adapter: https://www.llblgen.com/Documentation/5.5/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_dataaccessadapter_adapter.htm#multi-tenancy-support-catalog-specific-persistence-info-sql-server-mysql )
So you can have an llblgen pro project with the schema information under the name 'DevelopmentDB' and generate code from that, and at runtime rename 'DevelopmentDB' using the functionality described in the links above to whatever you need, e.g. 'ProductionDB' or 'BranchDB'. At runtime all 'DevelopmentDB' references are then replaced with the name you specified. This is done efficiently so no performance loss.
You can also rename it to "" so you can dictate what to connect with using the default database name in the connection string. ('initial catalog' for sqlserver)
Joined: 30-May-2019
Frans,
I am talking about changing the designer connected database. I know the designer can connect to many DBs in parallel but in my case I am connecting to only one. let me give you an example: I have a prod db with table A(Id,Name) and let's say I have created a model out of it.
on one new feature branch we need to add a Type column to the table. So I create a copy of the DB - Feature1 and a base reference copy - Feature1Base I now need to connect the designer project to Feature1 DB. I will make the changes in the DB table A(ID,Name,Type), refresh the DB scheme on the designer and then refresh the entity to have the new Type column
While the feature is still under development, another developer needs to change the same table and add an Address column So he creates a copy of the DB - Feature2 and a base reference copy - Feature2Base He now needs to connect the designer project to Feature2 DB. He will make the changes in the DB table A(ID,Name,Address), refresh the DB scheme on the designer and then refresh the entity to have the new Type column
Once feature 1 is approved, we merge the DB and llbl project into the development branch (no conflicts)
Once feature 2 is approved we cannot merge it directly as there will be conflicts. So we use the Feature2Base, Feature2 and the Production DB to do a three way merge of all into the Prod DB. For the llbl project we do a 3 way xml merge
This has been working great for us with Telerik ORM for years (but the same should work in any ORM as long as it has a text based orm project and/or no project at all - we use for telerik the fluent model so no designer and no project at all). Usually I have around 15 feature DBs open all the time with code branches attached to them as they make changes to the DB.
Joined: 17-Aug-2003
DaniAvni wrote:
Frans,
I am talking about changing the designer connected database. I know the designer can connect to many DBs in parallel but in my case I am connecting to only one.
Ah ok. Just right click the catalog name in the catalog explorer -> Rename -> specify the name you want. Done. If you then use 'sync' it will pull relational model data from that catalog.
let me give you an example: I have a prod db with table A(Id,Name) and let's say I have created a model out of it.
on one new feature branch we need to add a Type column to the table. So I create a copy of the DB - Feature1 and a base reference copy - Feature1Base I now need to connect the designer project to Feature1 DB. I will make the changes in the DB table A(ID,Name,Type), refresh the DB scheme on the designer and then refresh the entity to have the new Type column
If you make sure the setting 'Add new fields after relational model data sync' is checked (Under database first development) which is the default, the field should be added automatically.
While the feature is still under development, another developer needs to change the same table and add an Address column So he creates a copy of the DB - Feature2 and a base reference copy - Feature2Base He now needs to connect the designer project to Feature2 DB. He will make the changes in the DB table A(ID,Name,Address), refresh the DB scheme on the designer and then refresh the entity to have the new Type column
Once feature 1 is approved, we merge the DB and llbl project into the development branch (no conflicts)
Once feature 2 is approved we cannot merge it directly as there will be conflicts. So we use the Feature2Base, Feature2 and the Production DB to do a three way merge of all into the Prod DB. For the llbl project we do a 3 way xml merge
This has been working great for us with Telerik ORM for years (but the same should work in any ORM as long as it has a text based orm project and/or no project at all - we use for telerik the fluent model so no designer and no project at all). Usually I have around 15 feature DBs open all the time with code branches attached to them as they make changes to the DB.
I'd merge the schemas in productionDB and then simply sync the llblgen pro project with that. Should be easier than doing a 3way merge in xml, as it's information that's a reflection of the ground truth database schema anyway (the production DB after those schemas are merged)
The main issue is the underlying 'what's the source of truth' for your final model? You have two versions which are developed in parallel and although textmerge techniques can get you very far, in the end it comes down to what will be the truth for the entity model to be based on. So once that's been established, e.g. by merging the relational schemas in 'productiondb', you can base your entity model on that using a sync with that catalog.
Joined: 30-May-2019
Frans,
thanks for the quick reply! Indeed it works but I have to say it is very confusing. I would expect rename to logically rename the entity in the scheme explorer; not change the connection string. as a side note (not that we need it) but if a user wanted to connect to a different SQL machine and change the DB the rename would not suffice. I think some better UX should be provided for this
Joined: 17-Aug-2003
DaniAvni wrote:
Frans,
thanks for the quick reply! Indeed it works but I have to say it is very confusing. I would expect rename to logically rename the entity in the scheme explorer; not change the connection string.
I think you're confusing two things 1) You can rename the catalog name in the catalog explorer so you can point the designer to a different catalog to pull the relational model data from, and 2) you can at runtime (so when the code has been generated, with the name of the catalog in the project inside the mapping data) change the catalog name to whatever you want to point to a different catalog for a particular query or all queries.
No need to rename entities?
as a side note (not that we need it) but if a user wanted to connect to a different SQL machine and change the DB the rename would not suffice. I think some better UX should be provided for this
Yes it will. I have DBX on machine One and DBY on machine Two. They contain the same tables. I've created the project with DBX on machine One but now want to continue with DBY on machine Two as someone has just added a new table to that catalog. I rename the catalog in my project from DBX to DBY and start Sync. I then connect to machine Two, and I'll see the designer pull the tables from DBY as if I've always worked on that DB.
Not sure what should be done differently there, as there's little else to do?
Joined: 30-May-2019
I fully understand the ability to change the DB at runtime but I am focusing on the designer at the moment.
I finally figured out what you mean. I change the name of the DB and then on the sync structure I can connect to a different machine... I was expecting a simple "Change connection..." command on the context menu that would allow me to select a sql machine and a DB and click ok (like other apps have done). I guess it's part of the learning curve