Generation custom files from dbml file? - linq-to-sql

I've been having a look at making changes to the partial classes generated from a DBML file. I was reading into using the sqlmetal.exe tool but it appears that you can't do much customisation of what it actually spits out.
I'm wanting to make changes to the file for serialization purposes, I'd like to add the Data Member Attribute to specified properties in the generated partial classes.
Is this possible to do using the sqlmetal.exe tool or would I need to write my own tool for the file generation?

You could check out T4 templates or CodeSmith for file generation.

No it is not. You can accomplish this with Entity Framework.
http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx
Code written by Jaroslaw Kowalski works much the same way that Linq to SQL does.
It has some issues, but you can do everything with it, because you have the source. I'm going to publish my version soon(support for stored procedures, improved databinding experience and many other useful features)

If you want the datacontract and datamember attributes to be added, simply change the "Serialization Mode" property in the L2S designer's datacontext properties from "None" to "Unidirectional". All entity classes will then be datacontracts, and their members will be datamembers...

The upcoming Beta version of Entity Developer will contain highly customizable T4-like templates for code generation.
Also we have added functionality to divide the generated code into separate files.

Related

Interactive T4 Templates

I'm using a set of T4 templates in most of my MVC projects that create a set of Managers (think repositories), ViewModels and Extensions - utility extension methods such as ToModel(), ToViewModel() and ToSelectList(). So far so good. An enormous amount of basic 'plumbing' code is now written for me.
What I'd really like is an ability to configure variables that are used within those templates from an external file and then have the template use that file when executing.
I know I can run another T4 template from within another, but I can't find a way to add configuration in a separate file.
Presently, I include an 'Entity' table in my database and use that for configuration. It works but it feels dirty to have this in the database.
T4 is just C#/VB.Net code in the end, you can pretty much use any libraries you want. If you want an external configuration file you could use json.net and a simple json file in your project. At the start of your template, use the file io in the framework to read your json files contents, pass that to json.net and then extract the parameters you need. The most common way to use json.net is to serialize and deserialize classes but it also gives you access to a lower json dictionary like object that you can use linq to get any data you need from the json.
But remember there is always more then one way to solve a problem and this is a problem I have been trying to solve for a while. My preferred solution is an extension that I have created called T4 Awesome. My extension takes a totally different approach to using T4 for scaffolding inside Visual Studio. I add multiple tool windows and context menus around the IDE to make managing and using T4 templates faster and easier. I have a dynamic UI that lets you define simple parameters and pass them to your templates and also give you much more control over the final output files location. Feel free to check it out. And full disclaimer, I charge for this extension but have a free community version that should be able to do what you want.

Visual Web Developer 2008 won't auto generate classes from Linq

I'm new to Linq and Visual web developer 2008 Express. I have read some posts here and Scott Guthrie's on setting up Linq, but I'm a little stuck because the classes aren't auto-generating as I thought they would. I have setup a database with a simple table (with the Primary Key as the ID, and it is set to auto-increment) plus a few other columns, and dragged and dropped it on to the DBML Linq designer pane. The table appears in the window, but no classes are auto-generated. When I right click on the table and select "View Code", DataClasses.cs is displayed, but I only see a partial class with no methods or properties.
Isn't Linq supposed to do this, or have I (quite likely) missed the point completely? Or is this functionality not available in Visual Web Developer 2008 Express?
No, you're not missing anything. That is exactly how it should work. Go to solution explorer, expand the dbml, and double-click on whatever.designer.cs. Down at the bottom, you'll see ...
[Table(Name="dbo.YourTable")]
public partial class YourTable: INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
... and all of your properties.
As the other answerers have already pointed out, you do get your code generated - into a single (modelname).designer.cs file.
This may or may not be what you expected and wanted - if you can live with it - perfect!
If not, there's at least one set of Code generation templates out there called PLINQO which are based on CodeSmith, the well known code generator. Those templates allow you to do a lot of things standard Linq-to-SQL doesn't support:
generate classes for each table into their own, single file in a user-definable folder
actually update your DBML model and all associated generated classes if the underlying database changes
adds a "(entityname)Manager" class to manage entities of a given type (like Customer etc.)
All in all, it's quite a neat solution to handle Linq-to-SQL code generation. Excellent stuff - recommended!
Marc
As mentioned, LINQ-To-SQL will not actually generate individual class files for you - if you go and write some code that references a class for one of your tables, you will find that it is there...

Is there a simple Linq to SQL generator with bi-directional serialization attributes?

I'm trying to find a way to generate Linq to SQL classes with bi-directional serialization attributes. Basically I want a DataMember tag (with an appropriate order) on every association property, not just the ones where the class is the primary key (like the Visual Studio generator and SQL Metal do). I checked MyGeneration, but didn't really find anything that worked for me. I thought the T4 Toolbox was going to be my solution, it would be quite easy to modify it to add the attributes, but I get an exception on the calling side of my WCF service, and I've gotten no response back on the issue. I'm about to try installing CodeSmith and using PLINQO, but I'd prefer something free.
I'm pretty close to just writing my own T4 generator, but before I do that, I was hoping to find an pre-built solution to this rather simple problem first.
I ended up writing my own code generator for our L2S classes. We actually generate two sets of classes. One is a "lightweight" set of entities for client application use. These classes have no L2S plumbing. But they have the full datamember attributes with proper order. Then we have our L2S entities, which are strictly for backend use. This has worked out quite well.
Be careful using PLINQO. I've looked at that product extensively. In fact, much of my code generator is based on the code PLINQO generates. However, they have a "major flaw" (their words) in how they have implemented many to many relationships.
You might want to also look at a product named "Reegenerator".
Randy
This turned out to be the solution to my problem. I had just resigned myself to start researching my own generator when I stumbled upon that. It has a bidirectional serialization option and it works great! Here's a link to the author's bog, which contains a great video example of how to get started.

Linq-to-SQL Design question!

What if you need to create POCO objects from a dbml file? Do you use a generator and who? You write the POCO's manually?
Say you like to make your objects Persistent Ignorant and share to clients, then create a DAO pattern for the communication between Client - DAO - L2S Objects, this is a question for disconnected design using Linq 2 SQL. Supposed that the POCO's using the client should be as much as primitive as they can be without dependencies (EntityRef<>, EntitySet<>, Attributes, etc.), and ofcourse you could cast the L2S object into the POCO with the appropriate DATA.
Any help and any corrections on the concept would be really helpful!
I would be tempted to say "wait until EF in .NET 4.0", which has much improved POCO support (compared to EF current) and hopefully a POCO T4 template in VS2010.
At the moment SqlMetal will emit rich objects; while LINQ-to-SQL can work on POCO types, you would have to write the POCOs yourself, or use xslt / T4 / whatever on the dbml.
SqlMetal can emit an XML mapping file from an input DBML file via the /map[:file] switch. This removes attributes from the generated class files, which is a step closer to POCO - you just have to remember to initialize your data context instances from the XML mapping file.
Removing EntitySet<T> and EntityRef<T> references is harder, and I'm not sure it's something I would recommend as you would lose a lot of useful functionality. However, it is possible - you need to manually manipulate the DBML file that you pass to SqlMetal by removing all <Association> elements. You could do this using LINQ to XML as a custom step in your build process, for example.
This would basically disable associations in the output mapping file and classes, as SqlMetal will only generate EntitySet / EntityRef code for <Association> mappings. You lose the ability to manage parent-child relationships automatically though.
That would give you a pretty close POCO pattern - the only other thing you would get is the INotifyPropertyChanging implementation, but I think you could justify hanging onto that as it is fairly generic.
If that doesn't meet your needs then you could look at doing your own code generation - check out T4 templates for LINQ to SQL which works in VS 2008 and is based on SqlMetal, but you have the option to totally customize the output to suit your needs as it uses T4 for template specification and output generation.
We also use Linq2Sql and need to write own model classes from L2S results. After lot of googling I've found T4 POCO Templates for Linq2Sql and EF which uses .dbml or .edmx files as a source and create own POCO entities.
Link to download at the bottom of the article or duplicated here.
We used it as a base and then customized it for our needs.

Missing Linq namespaces (Linq to sql, compact framework)

I spent this morning in trying to figure out where the system.linq.expressions namespace is. The following is what I did:
In VS 2008, Create a new C#/Smart Device/Windows Mobile 6 Professional SDK/.NET CF v3.5/Class Library
Used SqlMetal (in Program Files/Microsoft SDKs/Windows/v6.0A/Bin) to generate the data context.
Added the data context .cs file into the project.
Compile and many errors for missing namespaces: System.Data.Linq, System.Data.Linq.Mapping, System.Linq.Expressions
After some research added System.Data.Linq.dll in c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5 (The dll was not directly listed when I choose to add reference and I used "browse" tab to finally located the one, which is for normal framework)
Compile again, less errors, but still System.Linq.Expressions namespace is missing.
The document says System.Linq.Expressions is in System.Core.dll but it seems my System.Core.dll (located in Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE) contains much less namespace than document says.
Thanks in advance!
The Compact Framework does not support LINQ to SQL. All objects in the documentation for System.Data.Linq confirms this by being completely devoid of the "supported in the CF" icon. For example, look over at the docs for DataTable, which is supported. You'll see a little icon by each supported method/property.
You cannot "add" support by simply referencing a desktop assembly like you did in your step 5. The CF cannot consume full framework assemblies, for a variety of reasons.
Dynamic code generation (Reflection.Emit) is not available in NETCF. What this means is that a lot of features that depend on this is not available, this includes DLR (dyanmic language runtime and hence languages like IronRuby), Linq-to-SQL/
If you just want the Linq.Expressions and you are doing your own stuff with it i.e. not trying to get linq to sql working then you can use the System.Linq.Expression stuff from the db4o guys.
I am using it on my project using linq to objects.
db4o linq implementation