views:

398

answers:

5

I have a very interesting problem on my LinqToSql model. On some of my tables i have a references to other tables and in LinqToSql this is represented by a EnitiyRef class, when you are trying to access the references table LinqToSql will load the reference from the database.

On my development machine everything worked fine (the references were loaded perfectly) but last night i uploaded the changed to our production server and started getting NullReferenceExceptions when trying to access the reference on my tables.

Sample code:

var sale = db.Sales.Single(s => s.ID == 1);
string username = sale.User.Name;    // User is a reference to a User table
                                     // LinqToSql will automatically load the
                                     // row and access the fields i need.

// On my server the sale.User throws an exception that its null (User) but the user
// is definitly in the database (there is even a FK constraint from Sale to User)

At first i thought that it my DataContext got GC'd but i double checked everything with no result (besides it works on my box).

(Everything is the same on the server and my box, same dll's, same db schema etc...) (I actually copied the entire DBF file over to my server so its the exact same schema)

+1  A: 

Have you turned the context logging on and compared the results on your dev box to those on your production box?

Jon Skeet
Thanks for the answer. The context did reveal one thing that the AttributedMetaModel had a different version on the server then on my machine, turns out that the sysadmin installed 3.0 SP1 and not 3.5 SP1. how confusing (and how lame). Thanks anyway.
James Z
+1  A: 

If you move your source to the production server and compile it there, try regenerating the generated source for the DataContext. You can do this by running "run user defined tool" from the context menu of your DataContext source file.

If both share the same binary, make sure the database definition is exactly the same in both databases. A small difference like one column being nullable on your production server but not nullable on your devbox can make all the difference.

Sam
Updated the question to clarify this.
James Z
+1  A: 

In order to find and resolve an issue like that it would be helpful with a stacktrace and perhaps a profiling on the database.

The problem could perhaps be a security issue. Have you tried to log in with the same credentials in Management Studio as your application uses and do a select on the table.

That would at least give you an idea about security or a linq issue.

bovium
The user im using is the owner of the database.Sql profiler does not show any traffic other then the original one for the primary table (Sale)
James Z
Are you sure you have modelled you reference correctly and that there actually exists data on the entities you reference?
bovium
Have you made a 1-1 relationship or a 1-many releationship?
bovium
A: 

Examine DataContext lifetime. There may be stale cache at work here

For example:

  1. Context1 : Load Sale with ID == 1. Examine its User property and observe null User.
  2. Context2: Load Sale with ID == 1. Modify User property by adding a new User. Commit.
  3. Context1: Load Sale with ID == 1. Examine its User property. Yup, still null (it's cached!!).
David B
A: 

One possibility is that you connection string used by your DBML is still pointing to a database server other than Production.

This happened to us whenever a LinqDataSource was used directly in an ASPX page, and thus the DataContext was using the default constructor, which was pointing to a connection string based on the database that the last developer used to import the DBML.

What we did was create a DataContext object that inherited from the generated DataContext and overrode the default constructor with the correct connection string from our web.config.

Even Mien
The connection string is actually the same, but its not a problem since its based on 127.0.0.1 so it should work (and it does load the initial entity) besides my server is on the internet and im under a firewall.
James Z
BTW i use another solution when i need a different connection string on my production server. I set the connection string on the DBML file to (none) this causes it not to generate the parameterless constructor, then i add a static method that new's up a context with a string from a config file.
James Z