Using Linq to Sql w/different environments/connection strings - linq-to-sql

Fairly simple question that I can't remember. We have three environments: Local machine (unique for each developer), Development, and Production. Connection Strings are in a config file (not web.config, but web.config points to the file); only one is active at a given time (the other two are commented out; all three have the same name but different values for each environment).
I'm using a rudimentary version of the ActiveRecord pattern to handle data access (i.e. static GetByProperty methods in the Linq-generated CS file). To ensure that all of us can use the Linq classes without having to muck about with the designer, all I would have to do is pass in that configuration setting with the connection string (e.g. ConfigurationManager.AppSetting["TheConnectionString"]) when I new up the DataContext, correct? I am going the approach of newing up a context per request; is there any issue (other than DRY, as I'd be repeating the whole connection string every method) I should be aware of passing the connection string in every time, or is that standard operating procedure?

You chose two of my least favorite things (ActiveRecord and LINQ to SQL). ;-) Regardless, you can move the code to a factory method (or similar) to avoid the DRY issue, if that particularly bugs you. You will likely have to do a small bit of refactoring and re-architecting, but you can solve that issue later.
As for changing connection strings to be environment specific, that is fairly standard operating procedure, whether you are using LINQ, DataSets, EF, or otherwise. Location of the actual persistant store is a configuration issue.

Related

Why does LinqPad create Fields instead of Properties?

I recently took on a project of creating a tool for LinqPad that would Dump query results into CSV format in order to use the tool on massive databases for quick results. One thing I wanted out of the tool is for it to be able to work in Visual Studio, and LinqPad. Thus, if I was using LinqtoSQL in VS2010, or LinqPad, I could dump results quickly to a csv file, and then open it up into Excel to view the results.
The biggest hiccup in the project came from how LinqPad builds their DataContexts vs. how Visual Studio builds their DataContexts. The best information I could find on how LinqPad does it comes from here. Basically what I found from my project, was that VS2010 creates properties for their DataContexts, but LinqPad creates Fields. Thus when using reflection:
LinqPad:
dataContextType.GetProperties() //returns 0
dataContextType.GetFields() //returns the Fields from LinqPad created DataContext
VS 2010 LinqToSQL:
dataContextType.GetProperties() //returns the Properties from VS created DataContext
dataContextType.GetFields() //returns 0
So why does LinqPad use Fields instead of Properties in their DataContexts? Wouldn't it have been more feasible to copy the Visual Studio LinqToSQL pattern?
Update
Based on a comment I decided to ask the same question within the LinqPad forum as well.
This is a good question. The main reason for LINQPad using fields to map columns is for performance when building the typed DataContext that backs database-connected queries.
We're not talking about the speed of executing the properties themselves (there's actually very little overhead in executing simple accessors and the JIT may even inline them.) The overhead is when building the typed DataContext via Reflection.Emit. A field is simply that: one item of metadata, whereas a property requires emitting a field definition, a property definition, two methods for the accessors (each with IL to get/set the underlying field). Because users may point LINQPad to databases with upwards of 1000 tables and functions, this can add up in terms of the time taken to build the assembly - as well as its size (increasing HDD activity and working set).
You have raised an interesting issue in the lack of unification between PropertyInfo and FieldInfo in the reflection object model. It would be nice if there was an interface that unified fields and (non-indexed) properties.

Database and logic layer for ASP.NET MVC application

I'm going to start a new project which is going to be small initially but may grow to big over the years. I'm strongly convinced that I'm going to use ASP.NET MVC with jQuery for UI. I want to go for MySQL as database for some reasons but worried on few things.
I'm totally new to Linq but it seems that it is easier to use once you are familiar with it.
First thing is that accessing data should be easy. So I thought I should use MySQL to Linq but somewhere I read that it is not directly supported but MySQL .NET connector adds support for EntityFramework. I don't know what are the pros and cons of it. DbLinq is what I also heard. I would love if I can implement repository pattern as it allows to apply filter in logic layer rather than in data access layer. Will it be possible if I use Entity Framework?
I'm also concerned about the performance. Someone told me that if we use Entity framework it fetches lot of data and then filter it. Is that right?
So questions basically are -
Is MySQL to Linq possible? If yes where can I get more details on it?
Pros and cons of using EntityFramework or DbLinq with MySQL?
Will it be easy to access data using EntityFramework or DbLinq with MySQL?
Will I be able to implement repository pattern which allows applying filter in logic layer rather than data access layer (when I use EntityFramework with MySQL)
Does it fetches hell lot of data from database and then apply filter on it?
If it sounds too many questions from my side in that case, if you can just let me know what you will do (with a considerable reason) in this situation as an experienced person in this area, that should answer my question.
As I am fan of ALT.NET I would recomend you to use NHibernate for your project instead of EntityFramework, you may google for the advantages over it, I am convinced you'll choose it.
Based on the points you've mentioned, then I would seriously consider going with MS SQL instead of MySQL initially and implementing LINQ-to-SQL instead of Entity Framework, and here's why:
The fact that you are anticipating a lot of traffic initially tells me that you need to think about where you plan to end up, rather than where to start. I have considerably more experience with MS SQL than I do with MySQL, but if you're talking about starting with the community version of MySQL and upgrading later, you're going to be incurring a significant expense anyway with the Enterprise version.
I have heard there is a version of LINQ that supports MySQL, but, unless things have changed recently, it is still in beta. I am completing an 18-month web-based project that used ASP.NET MVC 1.0, LINQ-to-SQL, JavaScript, jQuery, AJAX, and MS SQL. I implemented the repository pattern, view models, interfaces, unit tests and integration tests using WatiN. The combination of technologies worked very well for me, and I plan to go with the same combination for a personal project I'm developing.
When you get MS SQL with a hosting plan, you typically have the ability to create multiple databases from that single instance. It looks like they give you more storage because they give you multiple MySQL databases, but that's only because the architecture only supports the creation of one database per instance.
I won't use the Entity Framework for my ASP.NET MVC projects, because I wasn't crazy about ADO.NET in the first place. I don't want to have to open a connection, create a command object, populate a parameter collection, issue the execute method, and then iterate through a one-way reader object to get my data. Once you see how LINQ-to-SQL simplifies the process, you won't want to go back either. In the project I mentioned earlier, I have over 60 tables in the database with about 200 foreign key relationships. Because I used LINQ-to-SQL with the repository pattern in my data layer, I was able to build the application using not a single stored procedure. LINQ-to-SQL automatically protects against SQL injection attacks and support optimistic and pessimistic concurrency checking.
I don't know what your project is, but you don't want to get into a situation where you're going to have trouble scaling the application later. Code for the end result, not for the starting point, and you'll save yourself a lot of headaches later.

Managing different developer's connection strings under LINQ to SQL

With my source in Subversion, I am having issues when 2 different computers have different connection strings.
The LINQ to SQL designer seems to only like having the same connection string.
Is it possible for the designer to use a connection string that varies since developers have different local configurations, but the actual usage in the web application pulls from the web.config?
Unfortunately, this is a huge source of pain with the LINQ to SQL designer. I do not know of a way to force visual studio to never add a default connection string when you drag tables or stored procedures onto the design surface.
We work around the issue thusly:
we never save our dev passwords
we never use the default connection string in code when newing up a DataContext
we can therefore "safely" ignore the multiple connection strings during sprints that touch the data layer
when things die down/become more stable, we delete the connection strings from the data context, either using properties of the designer surface itself or by editing the XML. At that point, it's up to the modifier of the data context to keep up with deleting the default connection strings.
Alas, this is not an ideal situation. Hopefully VS2010 will "fix" this issue.
I ran into this problem and found your question. Here's the solution we're now using:
Use a centralised Configuration class for retrieving config values from a particular location on the file system. This allows every machine where the code is running to use its own config values.
Create a partial class for the LINQ to SQL data context. Add a custom constructor that takes no parameters and retrieves the database connection string from the Configuration class described above.
For example:
public partial class MyCustomDBDataContext
{
public MyCustomDBDataContext() :
base(Configuration.GetDatabaseConnectionString())
{
}
}
This should now solve the problem both for developers and when deployed to test and production.
By following the guidelines on How Do I? Change Connection String of datacontext default constructor from web.config my application now uses different connectionstrings depending on if HttpContext.Current.Request is local or not.
//using System.Web.Configuration;
partial void OnCreated()
{
//Change this condition to your needs
var isLocal = HttpContext.Current.Request.IsLocal;
this.Connection.ConnectionString = WebConfigurationManager.ConnectionStrings[isLocal ? "localConnectionstring" : "otherConnectionstring"].ToString();
}

repository pattern with a legacy database and Linq to SQL

I'm building an application on top of a legacy database (which I cannot change). I'm using Linq to SQL for the data access, which means I have a (Linq to SQL) class for each table.
My domain model does not match with the database. For example, there are two tables named Users and Employees, and therefore I have two Linq to SQL classes named User and Employee. But in my domain model I'd like to have a User class which should contain some fields from either table (but I don't care about a lot of the other fields of these tables).
I'm not sure how I should design my repositories:
should the repositories perform the mapping between Linq to SQL classes (e.g. User, Employee) to the domain classes (User) and only return the domain classes to the application
or should my repositories return the Linq to SQL classes and leave the mapping to the caller
The first approach seems to make more sense to me, but is this the correct way to implement my repositories?
The purist (I try to stay pure) will tell you that your model represents your data. And therefore, anything that needs to be persisted is done so only when needed through repositories. Also, when you have complex entities, you want to use a service to combine them. For example, User + Employee = UserEmployee entity that is only accessible through an IUserEmployeeService.
With those vague statements, you have an excellent opportunity here.
Build an anti-corruption layer, which allows you to start moving off of the legacy DB at the same time.
This is an another chapter in the DDD playbook. An Anti-Corruption layer is used to interface with a legacy system using Facades, Translators, and Adapters to isolate the legacy DB with your pure Domain model.
Now, this may be a lot more work than you wanted. So, you have to ask yourself at this point:
Do I want to start the process of
moving off of this legacy DB, or will
it remain for the life of the
application?
If your answer is you can start migrating, then model your actual domain the way you want it. Persist it with normal repositories and services. Have fun designing it the way YOU want it stored. Then, use the services of the aggregate roots to reach into the anti-corruption layer and pull out the entities, store/update them locally, and translate into your domain's entities.
If the answer is that the legacy DB will remain for the life of the project, then your task is much easier. Use your domain's services (e.g. UserEmployeeService) to reach into the anti-corruption's UserFacade and EmployeeFacade (similar to a "Remote Service" concept).
Within the Facades, access the legacy db using the Adapters (e.g. LegacyDbSqlDatabase) to get a raw legacyUser(). The next step would be to use an UserTranslator() and EmployeeTranslator() mapper that converts the legacy user data into your actual domain's version of the User() entity, and return it from the UserFacade back to your UserEmployeeService, where it is combined with the Employee entity that came from the same place.
Whoa, that was a lot of typing...
With your Adapters and Facades of your Anti-Corruption layer, you can do your Linq-to-Sql or whatever you want to do. It doesn't matter because you have completely isolated the legacy DB/system away from your nice and pure Domain - your domain that has its own version of User() and Employee() entities and value objects.
DDD and Linq To SQL don't go together very well because the generated classes are not meant to deviate significantly from your DB table structure. You'll have to either map your classes in a way that makes working with Linq to SQL a pain or just live with a non-ideal object model.
If you really want to utilize DDD and the repository pattern go for Entity Framework or even better NHibernate.

Multiple DBML files - type sharing?

I have a Client/Server application, where the Client and Server have some common tables (which are kept in synchronisation as part of the application).
We currently store these tables (i.e. FileDetails) in a Shared.dbml file. Until now, any stored proc that returns a result of set of FileDetails, has been placed in the Shared.dbml (even it is a Server-only) SP.
I released that the LINQ to SQL supports a Base Class property on the DBML, and I thought that perhaps I could have a Server.dbml, that extends my Shared.dbml. In theory this would give me a ServerDataContext with all the shared tables and SPs, as well as the server-specific elements. Normally in the SQL designer I would drag and drop the SP, over the FileDetails table to show this is what was returned, however as the class is in a different DBML this is not possible, and in the XML I don't think the ElementType IdRef="1" approach will work (as the ref needs to point to another file)
I found I can get around that problem by editing the XMLs return type manually:
<Function Name="dbo.SELECT_FTS_FILES" Method="SELECT_FTS_FILES">
<Return Type="ISingleResult<DataTypes.FileDetails>" />
</Function>
My question is, does anyone have any experience with this kind of approach, and could point me to further resources? Are there any obvious drawbacks to it (other than than manual XML updates)
All feedback welcome
You could inherit from your datacontext. However in your new datacontext you wouldn't be able to use the linq designer you would have to code things out manually.
Is there any reason you don't want two datacontext?
Inheritance and LinqToSql don't play nice together in general. If you have a deep need for it you should look into another ORM like NHibernate.