I use code-generation for my data access layer and Doxygen for documentation. My problem is that I can't add Xml comments on the generated classes since they will be overwritten as soon as I re-generate the code. To be more precise I can add Xml comments to my custom methods (which are in a separate file as partial classes) but I can't do it on data properties.
Any suggestions?
With Doxygen, you don't have to write your documentation scattered throughout the file, so you can keep it separate from the generated code and prepend it to the generated file as a post-generation step.
Keep the documentation in your model, and have your CST templates pull out & write that information to the generated code.
For example, you can comment (is comment the right word? Maybe the field is called summary) tables and columns in your SQL database - i know of a few codegen solutions that automatically put that text into your code...
Related
At work, we have multiple telegrams to communicate with a customer. Those telegrams are always different with each customer, but the logic, how we work with them is always the same. The data is sent to a table on our schema with other data for example like sent time and telegram type. We split it into a view to simplify it for development and testing purpose.
Example JSON:
{"Prop1": "Test"}
Example view script (using Oracle Enterprise):
CREATE OR REPLACE VIEW test
AS
SELECT prop1
FROM telegram
, JSON_TABLE (
telegram.json,
'$' COLUMNS (
prop1 PATH '$.Prop1'
)
)
My problem is now, that I do not know the correct or good way to create those view scripts with C#. Currently, I use a constant string with placeholders ({0}, {1}, ...) but they are getting really hard to maintain. I also read about T4, but it is only useable with Visual Studio. AFAIK we plan to move to .NET 5 and it looks like T4 is not available anymore and/or you cannot call the created C# classes in the code without some errors. I heard about Roslyn, too. Is it possible to create .txt/.sql instead of .cs files?
I hope I got all the information needed to answer this question. If I forgot some information, tell me. Thanks in advance!
Is it possible to create .txt/.sql instead of .cs files?
Sure, you can add the .txt/.sql file to your project and set its build action to "Embedded Resource".
In your code, you can access the content of that resource with Assembly.GetManifestResourceStream or by linking it to a resource file. Afterwards, you can apply String.Replace or String.Format for placeholders, if required.
That having been said, you might want to consider storing your data as relational data in your database, instead of JSON text that needs to be parsed by a for Every. Single. Query. Not only will this allow you to get rid of your view, but it will improve performance and allow you to use indexes on relevant fields.
I'm using Entity Framework Reverse Engineer Code First on an existing database. The classes are created properly but I need to change the entity names. I want to prefix every entity class with "EpiFlex". If a SQL table name is Users, the resulting entity should be EpiFlexUsers and the output file should be EpiFlexUsers.cs.
Is there a tag of some sort that I can add to the beginning of the T4 files to have that prefix added automatically or do I have to painstakingly go through each file and put the prefix ahead of the auto generated code?
Or maybe I'm totally missing the point. Is there another way to specify custom naming of the entities?
There doesn't seem to be any quick and easy way to do this. However, Programming Entity Framework 2nd Edition is an excellent book that I've come to consider absolutely essential if you're going to really get into entity framework. This book also has a lot of help on editing the T4 files. I haven't digested the complete section on T4 editing yet so maybe I'll still find something that shows how to very easily do what I want.
Here is a link to the book. http://shop.oreilly.com/product/9780596807252.do
I am working on a library that builds fairly large XML files (e-commerce offers).
I use business classes (such as ProductInfo, PriceInfo etc.) and I generate the resulting XML out of these.
My latest task is to implement functionality that allows to generate this XML out of CSV input files.
The CSV files do not have any predefined format and it is user's task (we provide an application that allows them to do that) to map all the CSV columns into their respective counterparts in our fixed XML format.
So basically their job is to assign each column to one of my bussiness classes fields: "all data from this column goes into ProductInfo.ShortDescription etc.".
Our format is likely to change in future - it keeps on being updated and extended - and so I would like to make my implementation as generic as possible.
The solution I considered is following:
the library returns names of all the available / required fields
our user maps CSV columns to those fields
I implement a custom attribute (containing a field name - string) and mark all the fields in my business classes with it. So once they've mapped all the columns and submitted the data in CSV, my library starts creating ProductInfos etc. assigning input values to fields, identified by the attribute name. This would be done by reflection.
Is this a good idea? I have some concerns regarding performance (I know that reflection is slow), although I'm not sure how much of an issue that would be. Is there any other issues I should be aware of? Are there any better alternatives?
Why not just set up a web service to handle these for the end user? If you make changes to your business objects, which are exposed through the service, the schema for the WSDL service will automatically update. This will give you the ability to strongly type your data through a schema automatically.
does anyone know how of a tool where I can point to my sql server database and it reads the schema and generates c# interface classes from the tables?
for example - say I have a table called 'Customers' with a "Name" column, "Address" Column and a "Phone" column it would generate a ICustomer.cs file with string Name {get;set;} string Address {get;set;} and int Phone {get;set;}
I am using a 'incomplete' code generator and it does not generate these interfaces.
How about the Linq to Sql O/R Designer?
I don't know of a tool doing it, but I know for sure that you can do it yourself quite easily!
Set up a string containing the header of the class, and another with the footer.
Then, create a new text file named as your table.
Write the header into the file.
For the body, just write a loop reading your table, which extracts the names and types of the fields, and writes an interface with that info.
At the end, write the footer to the file.
There you go with your brand new interface!
(As interfaces are juste plain text files, it's really easy...)
You could use SQLMetal.exe to get part of the job done. IT sounds like you want an interface, but this will create concrete classes. It'd be a small task to find/replace class with interface, and modify the names.
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SqlMetal.exe or open a Visual Studio Command Prompt.
Usage: sqlmetal /server:myserver /database:myDB /user:myUser /pwd:myPwd /language:csharp /code:myDB.cs
More options over at the MSDN page for SQLMetal.
You need a tool that allows you to customize your code generation templates. Have you considered Enterprise Architect, or CodeSmith?
There are numerous others - you may even want to go for a Model Driven Architecture. Design your solution in UML and generate the database and the code from the UML model. You can use a combination of tools for this, for example MagicDraw and Maven.
I think I can use Resharpers 'Extract Interface' refactor as I have generated the class already.
Thanks for everyones input though
My SqlSharpener project lets you parse SQL files at design-time to create a meta-model which you can then use to generate any type of code you like in a T4 template. For example, you could create Entity Framework Code First entities.
You can also use MyGeneration
We have a big (and growing!) database. We're trying to not have to build the models by hand, and we found this
EdmGen2 which is supposed to build our EDMX entity models for us.
Since we have such a big database we'd like to not have all of our tables in the same Model. We got it all to work, but the generated model has all of our tables.
There is a read only list of the tables inside of the EntityStoreSchemaGenerator. It is (in fact) all of our tables.
Will this tool make a model that is less then our full database? Can we select which tables we want to put it and only use those?
The EdmGen2 code comes with an option called /RetrofitModel. The key point of this mode is that is runs some data mining algorithms to see if there are any obvious inheritance-like relationships in the database instance, and if so, generates an EDMX that includes those inheritances.
However, another feature of the /RetrofitModel option is that it allows one to select tables. For instance, if one has the AdventureWorks sample database, you can issue this statement:
EdmGen2 /RetrofitModel "Server=(local);Integrated Security=true;Initial Catalog=AdventureWorks;" "System.Data.SqlClient" "AVWorks"
It will bring up a list of the tables in the database, at which point you can check which ones you want to have in your model.
The tupleFraction parameter helps define what it means to be a "significant" subclass. The data mining rules are heuristics, and as such they can potentially find patterns where common sense might not agree.
The tupleFraction parameter says this (for some of the rules): if EdmGen++ thinks that it has found a subclass, but the new subclass has less than tupleFraction of the instances from its parent class, consider the new subclass "insignificant" and don't create it. The parameter is optional - if you don't specify it, I think that it gets set to 0.05 (5%).
The current version only allows table specification through the UI. However, to pull the list of tables from a file or from some other source is an easy addition - I will add it to the top of the to-do list for the next version.
UPDATE: We have updated the code at code.msdn.microsoft.com/edmgen2 to allow for tables to be specified without the GUI. In the previous version, the RetrofitModel option would bring up a dialog that would allow the user to choose the tables to include in the model. The ConceptualEdmGen dll now has two additional public methods that can set the list of tables without bringing up a dialog – one that pulls the list of tables from a file, and one where the list of tables is fed directly to the method as a list of strings.
The EdmGen2 code as it appears in the package uses the “from file” option, where it looks for a file called “Tables.txt” in the current directory, and if found, feeds its contents to the dll to set the list of tables. So for instance, if the following were the contents of the file “Tables.txt”:
HumanResources.Department
HumanResources.Employee
HumanResources.EmployeeAddress
HumanResources.EmployeeDepartmentHistory
HumanResources.JobCandidate
HumanResources.Shift
EdmGen2 would generate (for the RetrofitModel option) a model for all of the tables in the HumanResources schema for AdventureWorks. For both methods, an empty list will result in all tables in the database being added to the model. The table selection UI will still appear if neither table selection method is called.
I've just sent an email to the guy responsible for EdmGen2 lets see what he comes back with
Alex James
Program Manager, Entity Framework Team, Microsoft.
My solution to this was to create a variant of EdmGen2 which reads a Filters.txt file that contains not just table names, but text that gets parsed into EntityStoreSchemaFilterEntry parameters (Category, Schema, Name, ObjectType, FilterEffect). This allows me to generate models and assemblies which operate on specific views as well as tables - something that I don't think EdmGen2 does.
Of course that doesn't work with the ConceptualEdmGen, but since there is no source available for that I've elected not to use that component anyway.
One problem that I haven't solved is how to properly inject function definitions for stored procs into CSDL and MSL. I have it in SSDL but don't know yet how to do the others.