how do you generate class for LINQ to SQL? - linq

I am using linq to sql for my mvc 3 project. There are several ways to generate domain modal class files.
sqlmetal
Object Relational Designer
hand code
I always hand code those model class files. because files generated by sqlmetal or designer are messy. whats your opinion? whats the best way to do it.
EDIT:
I am using MVC 3, not 2. Maybe I am wrong, but this is how I validate. I gonna end up writing all those class files anyway, so whats the point to use tools to generate them???
public class User
{
[Required]
public string Password { get; set; }
[Required, Compare("Password")]
public string ComparePassword { get; set; }
}

We have hundreds of tables across multiple databases (one server). We do table first development, drag the tables onto different DBML designer files each in different folders representing different namespaces within each project. The designer files are marked not to compile, and we use a custom built T4 template that generates our code by reading from whatever DBML files are in the project. This lets us have full control of the code that's generated, so we can do things like implement an interface (IAuditable is one example where we have CreatedBy, CreatedDate, ModifiedBy, ModifiedDate). We can also put System.ComponentModel.DataAnnotations on our Linqed objects this way too without resorting to Buddy Classes. We have a second T4 template that's in charge of refreshing the DBML from the database, so we can ensure that tables have the 3 part prefix (db.schema.tbl) and so we don't have to delete and re-add to the designer. The XML just gets changed based on reading the db schema and updating the DBML. We also generate a repository/manager object for each POCO that have a few common query operations like GetByID(), and also handle commits and the audit logging. These managers get extended with all the custom queries you'd need to write against each table, and they own the DataContext. This design is sometimes known as the "Mommy-may-I?" approach, where the object Linqed to the table has to ask its manager to do everything for it.
I've found this to be a very versatile and slick way of doing L2S, and it's made our back-end development a breeze so that we can put our focus on the user experience. The only downside is that if we do associations across namespaces, you have to manually add those to the partial class yourself, because otherwise you'd have to add that foreign table to another DBML in order to draw the association. This is actually not such a bad thing as causes us to really think about the specificity of our namespaces and cut down extra ones. Using T4 this way is a great way to develop DRY (don't repeat yourself). The table definition is the only place you need to change the structure and it all propogates. Validation goes in one place, the POCO. Queries go in one place, the manager. If you want to do something similar, here's a good place to start.

Even tho the Designer generated classes are messy, what does it matter to you?
There's, I dare say, absolutely no need to ever open one of the design files.
If you need to extend any of the entities defined in your model, they are all partial classes so you can just create your own partial class of the same name and implement your stuff...
When I do use L2S, I just use the designer.

Related

Entity Framework: Implement interface when generating from database

I'm having a few tables on SQL Server, which have similar structure - int Id and string Value.
This tables linked to main table via foreign key, so I'm wrote a bit of logic for mapping a string values to id's in models in MVC Razor. This feature requires that models used as dictionary implement simple IKeyValue interface with Id and Value, but after updating model from database I can loose interface implementation from models and must write it again.
Any way to automate this?
Are you modifying the auto-generated file? If so, you should not do this, for the exact reason you describe in your question -- it will get overwritten.
All of the classes in the generated file should be partial. You can take advantage of this by creating another class (in a different file, but in the same project), make sure it has the same declaration (and namespace), and have it implement the interface. This way the class will implement the interface, but will not be overwritten the next time you refresh the schema from the database.

How to debug problems with The Entity Data Model Designer (Entity Framework)

I have inhereted some project which uses Entity Framework in a way which makes it hard to make there any changes. It uses QueryViews for almost all tables (cca 50 tables) and of course stored procedures. Now I have to change there quite a lot of things ... rename tables, add tables, change columns etc.
When I tried to use the "Update Model from database ..." wizard, than after the update (where I added/removed the tables and let refresh the others using the wizard) from the database the Entity Data Model Designer rendering stops working ... there is just blank window with the text "The Entity Data Model Designer is unable to display the file you requested."
So I tried different approaches (like manually editing the edmx file), but the problem remains. The editor shows only the "The Entity Data Model Designer is unable to display the file you requested."
The mapping using QueryViews makes it probably more complicated. It is well known that the designer can not work with the QueryViews properly (one can not edit them using the designer) and the Entity framework engine even does not recognize that the columns from CSDL are mapped using the QueryViews and complains on each and every column (which is mapped using QueryView) that "Error 11009: Property 'XXX' is not mapped." I see exactly 100 errors like this. Maybe somewhere after the 100th error, there is some hint (in the form of other errors) how to fix the issue with Designer, but I don't know how to see them. The 100 limit is most likely hardcoded in VS2010 (http://stackoverflow.com/questions/2880936/how-to-increase-error-limit-in-visual-studio).
Btw. the code (classes for entities etc.) is generated without problems.
So, the question is:Is there a way how to see some log or something, where would be noted why the Entity framework Data Model Designer is not able to render anything?
Or is there at least some way how to see the rest of the errors (besides the 100 errors)?
Or does anybody know the ideal way of dealing with updating schema in EF besides using the wizard?
Try to add new EDMX and right click >> open with >> XML editor, then you can see a complete set in an empty model definition in EDMX. So you can compare the two EDMX and check notice which part of the EDMX is missing.
Here is the error link
In the end I have just do all the changes manually by editing the xml. However, I used the model designer (the GUI integrated in VS for EF) for creating the whole CSDL layer. So my approach was to carefully choose tables in the correct order and add them one by one in the multiple iterations of the following steps:
Use the model designer to create the csdl layer for the chosen table including all relations with already existing table. This at least ensured that the designer was usable later on and it saves the manual writing of the CSDL objetcs.
Write the SSDL layer, which should reflect the DB table.
Write the mapping layer (in my case using the QueryViews).
Try to compile and resolve all compile errors.
Repeat for next table (or more tables if you find it easier).
I hope this will help somebody.

LINQ DataContext Object Model, could it be used to manage a changing data structure

I am currently working on a project where we are rewriting software that was originally written in Visual DataFlex and we are changing it to use SQL and rewriting it into a C# client program and a C#/ASP.Net website. The current database for this is really horrible and has just had columns added to table or pipe(|) characters stuck between the cell values when they needed to add new fields. So we have things like a person table with over 200 columns because stuff like 6 lots of (addressline1, addressline2, town, city, country, postcode) columns for storing different addresses (home/postal/accountPostal/ect...).
What we would like to do is restructure the database, but we also need to keep using the current structure so that the original software can still work as well. What I would like to know is would it be possible using Linq to write a DataContext Object Model Class that could sort of interpret the data base structures so that we could continue to use the current database structure, but to the code it could look like we where using the new structure, and then once different modules of the software are rewritten we could change the object model to use the correct data structure???
First of all, since you mention the DataContext I think you're looking at Linq to SQL? I would advice to use the Entity Framework. The Entity Framework has more advanced modeling capabilities that you can use in a scenario as yours. It has the ability to construct for example a type from multiple tables, use inheritance or complex types.
The Entity Framework creates a model for you that consists of three parts.
SSDL which stores how your database looks.
CSDL which stores your model (your objects and the relationships between them)
MSL which tells the Entity Framework how to map from your objects to the database structure.
Using this you can have a legacy database and map this to a Domain Model that's more suited to your needs.
The Entity Framework has the ability to create a starting model from your database (where all tables, columns and associations are mapped) en then you can begin restructuring this model.
These classes are generated as partial so you could extend them by for exampling splitting the database piped fields into separate properties.
Have you also thought about using Views? If possible you could at views to your database that give you a nicer dataschema to work with and then base your model on the views in combination with stored procedures.
Hope this gives you any ideas.

LINQ to SQL classes to my own classes

I'm looking at using LINQ to SQL for a new project I'm working on, but I do not want to expose the LINQ classes to my applications. For example, do an select in link returns a System.Linq.IQueryable<> collection. As well, all the classes generated to represent the database use Table, Column, EntityRef classes and attributes. It's fine if my data access layer has LINQ dependancies, but I don't want my application to.
So my thoughts are that I will have to use the LINQ to SQL generated classes as intermediate classes that are not exposed outside of my data access layer, and create my own classes which the application can use. What is the easiest/effecient way to get the data from the LINQ to SQL classes into my own classes?
I totally agree with your thinking - I would try to avoid exposing LINQ to SQL entities directly to the world.
I would definitely recommend using a "domain model" of your own, either a 1:1 mirror of the underlying LINQ to SQL entities, or a different one.
As long as you have a domain model that is quite similar to the underlying LINQ to SQL entities, you can use tools like AutoMapper to easily shuffle data between your LINQ to SQL entities and your domain model classes. It should be pretty easy and flexible to do it that way!
Rob Conery published a webcast series entitled the MVC-Storefront where he introduces a variation of the repository pattern that accomplishes what you want.
I've used ideas from the screencast on a reasonably large project and was quite pleased with the results.
There are, however, issues with the pattern, particularly around concurrency and detached scenarios that you will want to think about up front before fully committing to it.
I detailed some of my pain with concurrency in this pattern here.
I'll be interested in the responses you get because I'm considering the exact same thing. I want to use the L2S entities classes on our backend but use much lighter-weight entities for application consumption.
Randy
I would advise against using LINQ to SQL on a new project, since Microsoft will no longer be developing this project, except for maybe fine-tuning some issues. LINQ to SQL is perfectly usable and is acceptable, but I would not advise new projects to use it. If you like LINQ to SQL, you should definately look into using Entity Framework instead of LINQ to SQL.
This is my current incarnation of how I am going about doing this:
I have a DataContext class that I created by adding a LINQ to SQL class, and droping tables onto the designer. I called the class MyDataContext and put it in a namespace called Linq. My database has a table called Tag, which generated a class, also in the Linq namespace. I changed all the accessors to internal, so they would not be visible outside of the data access layer.
namespace Linq
{
[System.Data.Linq.Mapping.DatabaseAttribute(Name="MyDb")]
internal partial class MyDataContext : System.Data.Linq.DataContext
{
...
}
[Table(Name="dbo.vTag")]
internal partial class Tag
{
....
}
}
I then created a class called DataAccess which is what will be exposed to any application that references the assembly. I also created my own Tag class. The DataAccess class and my new Tag class are in a different namespace called Data to avoid collisions with the generated classes which are in the Linq namespace. I use Linq to Sql to query for an IList of Linq.Tag objects, then I use Linq to generate me a list of Data.Tag objects from the Linq.Tag objects.
I'd like to hear comments on this to see if there's a more performant way to do this, or one that requires less code. I also wasn't too happy with my use of duplicate class names (Tag) so I'm interested to hear any ideas on naming suggestions too.
namespace Data
{
public class DataAaccess
{
public IList<Tag> List_Tags()
{
using (Linq.MyDataContext dal = new Linq.MyDataContext ())
{
IList<Linq.Tag> lstTags = (from c in dal.Tags select c).ToList();
return (from tag in lstTags
select new Data.Tag()
{
ID = tag.ID,
Name = tag.Name,
Parent_ID = tag.Parent_ID
}).ToList();
}
}
}
}
What you are proposing is having two separate models. That means boilerplate code, which I've found is not necessary. I have more or less the same idea as you, but realized that this would be useless. I've suggested Entity Framework in another answer in this thread, and I want to make that point again here.
What you end up with is a model-soup, where you have to maintain two models instead of just the one. And that is definitely NOT desirable.
To go from the LINQ to SQL classes to your classes is a matter of some fairly straightfoward LINQ to Objects (or just initialisation for single objects).
More fun is going back from your model to the LINQ to SQL objects but this is fairly standard stuff (although something I'm still working out or I'd find you some specific references).

Problem refreshing tables in the LINQ to SQL designer

I have been using LINQ to SQL for a while, and there is one thing that has always bothered me. Whenever I modify the schema of a table, in order to refresh it in the designer, I have to delete it and then add it back. That's fine, but this means I have to actually find the table in the designer. I have about 100+ tables in my database, and every time I do this, it's like finding a needle in a haystack. Well, maybe it's not that bad, but seriously, it takes way longer than it should.
Is there another option for refreshing tables that I am unaware of?
Some people use SqlMetal to 'refresh/update' their Linq2Sql designer. The designer does not have support for refreshing the schema, when the DB changes. You have to manually drop the table and re-add it back in.
ADO Entity Framework i believe can refresh. I've not used it, but I think I saw this at a TechEd demo this year.
Helpful Info: Google's results for SqlMetal.
This is not possible using the VS linq to sql designer.
You can do this using LLBLGEN PRO, a third party tool, instead of the built-in linq to sql designer. It isn't free but it does do a ton of other stuff as well, which of course you may or may not need.
LLBLGEN PRO is actually a full set of ORM tools, but also includes an enhanced linq-to-sql designer with 'refresh model from SQL' functionality.
See here for description of the issue - http://weblogs.asp.net/fbouma/archive/2008/05/01/linq-to-sql-support-added-to-llblgen-pro.aspx
And here for the tool - http://www.llblgen.com/
I don't do any customization of the content on the designer so after table changes I just hit CTRL+A followed by DEL. Then shift-select all of my tables and slap them back onto the designer. I don't have 100s of tables yet so not sure if things slow down at some point but with 20+ tables it just takes a second.
I have written an add-in that can do that (in both directions; database -> DBML or DBML- -> SQL-DDL diff script).
Unlike SQLMetal (or EF's "update model from database") mentioned in another reply, the add-in does a true sync/refresh; applying changes corresponding only to the differences between the model and the underlying db.
That means any customizations (renamed properties/navigation properties etc) that you have made in other areas of your model will not be removed/overwritten unless they are in conflict with the underlying db schema. (in which case you can still preserve them by adding them to the add-in's "exclusion list")
You can download it and get a free 30-day trial license from http://www.huagati.com/dbmltools/
I have a similar comment, thought it might fit in here for anybody out there Googling a solution to this issue...
When I change the columns that are returned by a stored procedure, deleting the procedure from the designer and re-adding it does not work. The custom return type entity that the designer generates does not reflect the changes to the SP.
I've tried disconnecting the DB in the server explorer, even deleting and re-adding the connection.
The only solution I've found is this:
1. Delete the SP from the designer.
2. Save the dbml file (or the whole solution, whatever)
3. Completely close Visual Studio.
4. Re-open Visual Studio and your solution.
5. Re-add the stored procedure to the designer.
I think that qualifies as a blue ribbon pain in the rump.
Anybody got a simpler solution?
PS- To those of you with 100+ tables: Go get a real (real == mature) ORM tool. I personally vote for NetTiers. It rocks. Used it for years with no (or at least very few) complaints. You'll probably have to buy CodeSmith to use it effectively, but it's worth it. The templates are open source. And there are templates for nHibernate as well. But I've found that I don't really dig on Java ports. If I'm gonna code on MS platforms I want code that was "born" there...
...editorial complete. :P
I have had simliar issues with the designer - the best thing I can suggest is creating multiple contexts for different areas of your data access - I broke mine down to as few a related tables as I could get away with for each functional area. You can re-use tables across contexts so it isn't a big deal.
There's a template for VS 2008 that replaces the designer, it should ease refreshing your LINQtoSQL classes: http://damieng.com/blog/2008/09/14/linq-to-sql-template-for-visual-studio-2008
There are a couple of other options:
Edit the .dbml file that the designer uses to draw the tables and generate the code. I've used this approach when the changes are small (adding a couple of columns, creating a simple table)
Use sqlmetal to create the required xml for the changed tables and move the declarations by hand to the .dbml file. This one is better for when the changes are either more complex or larger.
I personally detest using the designer, and I've had various issues with it whenever I've dared to use it.
I mostly use LINQ for very simple CRUD (no linked entities or anything), and if that's the case with you, it might be worth straying from the designer crutch. Especially since defining LINQ-to-SQL entities is as easy as this:
[Table("dbo.my_table")]
public class MyTable
{
[Column("id", AutoSync = AutoSync.OnInsert, IsDbGenerated = true, IsPrimaryKey = true)]
public Int32 Id { get; set; }
[Column("name", DbType="NVarChar(50) NOT NULL")]
public String Name { get; set; }
}
This way, all your entities have their own files, which makes finding them much easier, though you'll still have to add/update the properties manually.
Of course, if you'd refactor 100+ tables, that might not be an option ;)

Resources