I've read Rick Strahl's article on Linq to SQL DataContext Lifetime Management hoping to find some answers on how I would manage my .dbml files since they are so closely related to DataContext. Unfortunately, Rick's article seems to be focused on DataContext lifetime at runtime though, and my question is concerned with how the .dbml's should be organized at design time.
The general question of 'Best practices with .dbml's' has been asked and answered here, and the answers have focused on external tools to manage the .dbml.
I'm asking a more focused question of when and why should you not have a single .dbml file in your LINQ to SQL based project?
Please note that LINQ2SQL is intended for simple and easy way to handle database relationship with objects.
Do not break table relationship and units of work concepts by creating multiple .dbml files.
If you ever need to create multiple .dbml files (which i don't recommend), then try to satisfy the following:-
If you create multiple databases with no relationship between those database tables.
If you want to use one of these .dbml just to handle stored procedures
If you do not care about unit of work concept.
If your database is too complex, then I would consider ORM such as NHibernate, EF 4
In my opinion, you can split the .dmbl files so that each hold a subset of tables/procs from a DB according to function and relationship. I have not done this yet so this is just opinion.
I have however created multiple .dbml files to assist with unit testing. If you work in an environment which restricts you to using stored procs in your production environment then you cannot use the table part of the .dbml (you can use the proc part though). So if you "unit test" (this is really integration testing) the DB layer of your code you can call the proc wrapper and then check the results by querying the tables through the .dbml interface. In cases like this I'll split the .dmbl file into just the tables that I want to query in my "unit test."
Further info: I have 2 solutions that I build. One has unit tests and is never built on the build server. The other is built on the build server and deployed to test/production.
I'd say, you always just need 1 dbml-file PER database. If you have multiple connections to other databases, consider design or use seperate dbml-files. Either way, one is enough per database.
This because the dbml mapps to your tables and why not just use one "data connector" / "data layer" for that, seems odd / weird design to use more than one.
It's probably more controllable using only 1 aswell.
This issue has been thoroughly analyzed here: http://craftycode.wordpress.com/2010/07/19/linq-to-sql-single-data-context-or-multiple/
In summary, you should create at most one data context per strongly connected group of tables, or one data context per database.
Say you have a database:
Database D contains tables A, B, C, X, Y, Z where
Table A has a foreign key
relationship with tables B and C
Table X has a foreign key
relationship with tables Y and Z
Table X also has a foreign key relationship with table A
Say you have 2 DBML files P and Q based on database D
DBML File P contains entities A', B'
and C' where A' is connected to B'
and C' via associations.
DBML File Q
contains entities X', Y' and Z' where
X' is connected to Y' and Z' via
associations.
AFAIK, there is no way for DBML files P and Q to contain an association between entities A' and X'. This is the single biggest problem with having multiple DBML files.
To my mind, a DBML file reflects the data-model represented by the tables and constraints on those tables in a database. If some tables or constraints are missing from a set of DBML files, then the set of DBML files do not accurately reflect the underlying database.
Going back to our example, if there was no relationship between tables A and X in database D, then one would be able to create 2 DBML files.
Generically speaking, one can have multiple DBML files if each DBML file contains all entities and relationships that are connected. Note that the converse is not a problem, i.e., one can have a single DBML file containing multiple groups of entities that are not related to each other by any associations.
The answer is tricky because it's what the situation requires. I try to logically separate each DBML into contexts (after all, the DBML provides the DataContext functionality). So if my app has a single context, then it doesn't make sense for me to have a separate DBML for each table. Context is king when creating your DBML files is what I say.
Another thing to bear in mind is that LINQ uses the DataContext to track the identities of the instances of entities it creates. Therefore, an entity representing a row in a table created by one instance of the DataContext class is not the same as one created by another, even if all the properties are the same.
When one has multiple DBML files, then by necessity, there will be multiple instances of DataContexts, one for each DBML file. Therefore, entities can't be joined or shared from one DataContext to another.
This is applicable when an entity exists in both (or all) DBML files.
Related
I'm not so good at both Linq and SQL. But I have worked more with SQL and less with LINQ. I've gone through many articles which favors LINQ. I don't want to go the SQL way (i.e. writing stored procedures and operating data etc.)
I want to start with LINQ for every operation related with data. Here are the reasons why I want to do this:
I want to have complete control of my database via application and not by writing stored procs (as I'm not so good at writing store procedure)
I want to create my project as an easy maintainability view
Want faster development
For that, I know that:
I need to add a dbml file, drag and drop tables into that
Use dbContext class, and so on
But I want to know, is there a way:
I can avoid creating dbml file and still be able to access the database?
Do I need to use Linq to Entities for the same?
Will it be a good way to avoid using dbml file? Since for every database changes I need to drop and drop tables every time
Also I've come across many posts where linqToSql is considered deprecated and not a .net future?
I have so many doubts, but I think that's obvious when starting with a new technology?
I found this useful article which is good for beginners:
[http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx][1]
after doing some more research I came to conclusion that:
1)i can avoid creating dbml file and still be able to access database??
ANS Yes but instead of dbml now edmx files will be created.
2)Do I need to use Linq to Entities for the same?
ANS Yes you can go with linq to entities.
3)Will it be good way avoid using dbml file? since for every database changes I need to drop and drop tables every time
ANS it is not required to drop and create again the tables. their are options where you can update selected part of your database and you are not avoiding dbmls. it will created edmx file and that will almost similar to dbmls in many ways.
4) Also I've come across many posts where linqToSql is considered deprecated and not a .net future?
ANS yes in future development it will be depreciated. it supports only sql server as backend.
I hope I'm right. Please do tell me in case any other suggestions.
LINQ is a way to query and project collection of data. For example, you can use LINQ to query and shape data from a database or from an array. LINQ by it self has nothing to with the under lying database.
You use an ORM (Object Relational Mapper) technology to project data stored in tables of a database as collections of objects. Once you have the collection of objects, you can use LINQ to query them.
Now, you have many ORM technologies to select from, such as Entity Framework, NHibernate, Linq2Sql. If you don’t like to maintain a dbml file, have a look at code first approach offered by Entity Framework.
Then there are things called LINQ data providers. They would take a LINQ query, transform it to a SQL targeting a particular database, execute the query and get the results back as a set of objects. Many of the ORMs above has built in LINQ data providers as a part of them and would work behind the scene in fetching the data.
I would advise you to look up on some patterns such Repository and Unit of work for your data layer. When used correctly, these patterns will isolate your data access code from your applications upper layers. This will help you to change your data access technology is it becomes obsolete, without affecting the rest of the application.
LINQ is an awesome technology and you should definitely try it
I have composed the above answer based on my own experience and I am sure there are many SO users with better understanding of the above technologies than myself who may wish to add their own opinion
Good luck
I would like to find out how people out there manage the dbml file in a more scalable manner?
Do you have just one DataClasses1.dbml and drag every table into it?
Do you have separate files for separate logical groupings, eg Accounts, HR? If so, how do you visually see the foreign key relationships when one table has links to a table in another dbml file?
Thanks.
Better will be to use one single DBML file for all your tables, so that you can see all your relations i.e Foreign Key etc all together..But its depends upon your requirement totally..
Using Entity Framework (same for linq-to-sql) I like to use separate context classes for distinct parts of the database.
But what is "distinct"?
In most cases everything that is related to the core business of an application is too much interrelated for a separate context to be meaningful. But almost every application has lateral tasks like authorization, translation, auditing and so on. These are good candidates for separate contexts.
There will still be connections to the business logic though. As you probably know, you cannot join classes from separate contexts in a way that the join is translated to SQL. Only in memory. So it is useful to duplicate some entities in several contexts. So, for instance, both the business context and the authorization context will contain User entities. One context should be responsible for maintenance of the entity and the other one(s) should use it read-only.
Edit
By duplication of entities I mean that two (or more) contexts can have an entity that maps to the same table in the database. Like User. If you like, the business context could be for creating and updating users, the authorization context is (for instance) for adding roles to a specific user, without modifying the user itself.
I am working on an asp.net MVC 3 web application and I am using database first, but after I have mapped the DB tables into entity classes using entity framework, I am interacting with these tables as I will be interacting on the code first approach by dealing with Database tables as classes an objects.
So after mapping the tables into entity classes I find that the code first approach and DB first are very similar but except of start writing the entities classes from scratch (as in code first) I have created the entity classes from existing database tables - which is easier and more convenient in my case.
So are there specific cases on which i will not be able to do some functionalities unless i am using one approach over the other which till now i cannot find any?
Having dealt with many many headaches using db-1st EDMX pre EF 4.1, I am partial to code-first. But I'm not going to evangelize it.
In addition to the direct sproc mapping & function import features mentioned in Pawel's answer & comment, you won't be able to change the namespaces or any other code in the generated files when you use db-first. Afaik all of the files are nested under the .tt file. If there is a way to move them into logical folders & namespaces in your project, then I'm not aware of it.
Also if you ever want to separate your DbContext into a separate project from your entities, I recall this was possible pre-EF 4.1. But it was more cumbersome, because you had to run custom tool on both .tt files after each db change. With code-first this is pretty straightforward because you're dealing with pure OOP.
I think that the biggest limitation of CodeFirst (as compared to ModelFirst/DatabaseFirst approaches) is that you cannot map your CUD operations to stored procedures. If you are not planning to do that then you should be good to go.
To be more specific - You can invoke stored procedures using SqlQuery method on DbSet which will cause the returned entities to be tracked or more general SqlQuery and ExecuteSqlCommand on Database class (for Database.SqlQuery the returned objects do not have to be entities and there is no tracking for these objects). That's about it. You cannot map Create/Update/Delete operations to stored procedures. FunctionImports are not supported as well
EDIT
It's possible to map CUD operations to stored procedures in EF6 now
in early development stages the database is subject to continuous changes. I'm toying around with LinqToSQL and in most cases the Entity Model is just a 1:1 representation of the DB.
How can i keep the model up to date with the db changes?
Thanks.
I noticed that there is an "update model from database" command available if you right-click the Entity Framework design surface. I couldn't find such a thing for LINQ to SQL, so you might have to maintain by hand.
OTOH, it's just XML, so you could "just write some code".
The other thing to add is that I prefer the fact that in EF, I don't have to keep up to date with the physical database. I'm defining the entities that developers will use to access the data, and separately I'm defining the mapping between those entities and the logical database structure.
They don't need to be the same. If I want to split a table into two, or combine two entities into one table, I can do this, without requiring developers to rewrite their code.
This question is addressed to a degree in this question on LINQ to SQL .dbml best practices, but I am not sure how to add to a question.
One of our applications uses LINQ to SQL and we have currently have one .dbml file for the entire database which is becoming difficult to manage. We are looking at refactoring it a bit into separate files that are more module/functionality specific, but one problem is that many of the high level classes would have to be duplicated in several .dbml files as the associations can't be used across .dbml files (as far as I know), with the additional partial class code as well.
Has anyone grappled with this problem and what recommendations would you make?
Take advantage of the namespace settings. You can get to it in properties from clicking in the white space of the ORM.
This allows me to have a Users table and a User class for one set of business rules and a second (but the same data store) Users table and a User class for another set of business rules.
Or, break up the library, which should also have the affect of changing the namespacing depending on your company's naming conventions. I've never worked on an enterprise app where I needed access to every single table.
Past a certain size it probably becomes easier to work with the xml instead of the dbml designer.
I have written a tool too! Mine is for scripting changes to dbml files using c# so you can rerun them and not lose changes. See my blog http://www.adverseconditionals.com 4 more details
The approach that we've used it to keep 2 .dbml files. One of them holds the Stored Procs and all production DB access is done through this. The other is in a unit test folder and holds tables and their relationships and is used for DB data manipulation and querying for unit tests.
I have written a utility to address exactly that problem, I needed a quick app to let you select only the database objects you need. In my case I often needed a complex view, but no tables.
http://www.codeplex.com/SqlMetalInclude/